diff --git a/src/resources/cache/hashes.json b/src/resources/cache/hashes.json index 3c89f33f9751..b45f6077a465 100644 --- a/src/resources/cache/hashes.json +++ b/src/resources/cache/hashes.json @@ -1,106 +1,106 @@ { - "webgpu/shader/execution/binary/af_addition.bin": "9ad2b249", - "webgpu/shader/execution/binary/af_logical.bin": "ae4d0245", - "webgpu/shader/execution/binary/af_division.bin": "d3376690", - "webgpu/shader/execution/binary/af_matrix_addition.bin": "e3bc27b", - "webgpu/shader/execution/binary/af_matrix_subtraction.bin": "9cc3291c", - "webgpu/shader/execution/binary/af_multiplication.bin": "17f2a567", - "webgpu/shader/execution/binary/af_remainder.bin": "5582cf38", - "webgpu/shader/execution/binary/af_subtraction.bin": "de31266e", - "webgpu/shader/execution/binary/f16_addition.bin": "6cd9e104", - "webgpu/shader/execution/binary/f16_logical.bin": "8b97670c", - "webgpu/shader/execution/binary/f16_division.bin": "10202143", - "webgpu/shader/execution/binary/f16_matrix_addition.bin": "63f361ba", - "webgpu/shader/execution/binary/f16_matrix_matrix_multiplication.bin": "47fb7bc", - "webgpu/shader/execution/binary/f16_matrix_scalar_multiplication.bin": "89b49d2f", - "webgpu/shader/execution/binary/f16_matrix_subtraction.bin": "1c7c2571", - "webgpu/shader/execution/binary/f16_matrix_vector_multiplication.bin": "551ba6cc", - "webgpu/shader/execution/binary/f16_multiplication.bin": "e5c32f73", - "webgpu/shader/execution/binary/f16_remainder.bin": "404927e7", - "webgpu/shader/execution/binary/f16_subtraction.bin": "64188676", - "webgpu/shader/execution/binary/f32_addition.bin": "741c7a51", - "webgpu/shader/execution/binary/f32_logical.bin": "c761067f", - "webgpu/shader/execution/binary/f32_division.bin": "69aeed3a", - "webgpu/shader/execution/binary/f32_matrix_addition.bin": "10082f79", - "webgpu/shader/execution/binary/f32_matrix_matrix_multiplication.bin": "e82ac781", - "webgpu/shader/execution/binary/f32_matrix_scalar_multiplication.bin": "2bd684f", - "webgpu/shader/execution/binary/f32_matrix_subtraction.bin": "48da0bda", - "webgpu/shader/execution/binary/f32_matrix_vector_multiplication.bin": "8776a032", - "webgpu/shader/execution/binary/f32_multiplication.bin": "565152c2", - "webgpu/shader/execution/binary/f32_remainder.bin": "87e5fe4e", - "webgpu/shader/execution/binary/f32_subtraction.bin": "fd539f36", - "webgpu/shader/execution/binary/i32_arithmetic.bin": "d385729b", - "webgpu/shader/execution/binary/i32_comparison.bin": "a212a9e5", - "webgpu/shader/execution/binary/u32_arithmetic.bin": "d9387c9a", - "webgpu/shader/execution/binary/u32_comparison.bin": "cb609171", - "webgpu/shader/execution/abs.bin": "3161e44d", - "webgpu/shader/execution/acos.bin": "dc04c013", - "webgpu/shader/execution/acosh.bin": "5f2d5d46", - "webgpu/shader/execution/asin.bin": "7dcbb4e4", - "webgpu/shader/execution/asinh.bin": "a7826495", - "webgpu/shader/execution/atan.bin": "c38ef29f", - "webgpu/shader/execution/atan2.bin": "e3fe2caf", - "webgpu/shader/execution/atanh.bin": "7bbb6084", - "webgpu/shader/execution/bitcast.bin": "87bfa9e8", - "webgpu/shader/execution/ceil.bin": "e43ad5bb", - "webgpu/shader/execution/clamp.bin": "f59d5615", - "webgpu/shader/execution/cos.bin": "84722156", - "webgpu/shader/execution/cosh.bin": "cf071209", - "webgpu/shader/execution/cross.bin": "bf2f7adf", - "webgpu/shader/execution/degrees.bin": "c4254ee0", - "webgpu/shader/execution/determinant.bin": "e5fe08db", - "webgpu/shader/execution/distance.bin": "89368db", - "webgpu/shader/execution/dot.bin": "5902ed6a", - "webgpu/shader/execution/exp.bin": "fdbe406e", - "webgpu/shader/execution/exp2.bin": "69983959", - "webgpu/shader/execution/faceForward.bin": "56141bff", - "webgpu/shader/execution/floor.bin": "cc77695", - "webgpu/shader/execution/fma.bin": "63b076cc", - "webgpu/shader/execution/fract.bin": "46113f72", - "webgpu/shader/execution/frexp.bin": "7a578d2d", - "webgpu/shader/execution/inverseSqrt.bin": "b89e412c", - "webgpu/shader/execution/ldexp.bin": "2e387a8b", - "webgpu/shader/execution/length.bin": "1cf5a3d0", - "webgpu/shader/execution/log.bin": "d29e19c4", - "webgpu/shader/execution/log2.bin": "8493434a", - "webgpu/shader/execution/max.bin": "b3ac49b0", - "webgpu/shader/execution/min.bin": "7e92bdf4", - "webgpu/shader/execution/mix.bin": "a242b580", - "webgpu/shader/execution/modf.bin": "60c1b4c2", - "webgpu/shader/execution/normalize.bin": "d1c8e8ce", - "webgpu/shader/execution/pack2x16float.bin": "acd2d4cc", - "webgpu/shader/execution/pow.bin": "bd5ad2f1", - "webgpu/shader/execution/quantizeToF16.bin": "e1d5b687", - "webgpu/shader/execution/radians.bin": "ab8ffce", - "webgpu/shader/execution/reflect.bin": "21b95d6c", - "webgpu/shader/execution/refract.bin": "673f11a5", - "webgpu/shader/execution/round.bin": "e258877c", - "webgpu/shader/execution/saturate.bin": "ea81a5bb", - "webgpu/shader/execution/sign.bin": "506ea55a", - "webgpu/shader/execution/sin.bin": "a7343188", - "webgpu/shader/execution/sinh.bin": "958eb14d", - "webgpu/shader/execution/smoothstep.bin": "53d2d03f", - "webgpu/shader/execution/sqrt.bin": "bee99723", - "webgpu/shader/execution/step.bin": "5fd9e33e", - "webgpu/shader/execution/tan.bin": "7f4bdf13", - "webgpu/shader/execution/tanh.bin": "db866ad7", - "webgpu/shader/execution/transpose.bin": "5841777f", - "webgpu/shader/execution/trunc.bin": "7e39b544", - "webgpu/shader/execution/unpack2x16float.bin": "836d1dff", - "webgpu/shader/execution/unpack2x16snorm.bin": "c29710", - "webgpu/shader/execution/unpack2x16unorm.bin": "fee2226a", - "webgpu/shader/execution/unpack4x8snorm.bin": "fc72f2ee", - "webgpu/shader/execution/unpack4x8unorm.bin": "2e335e83", - "webgpu/shader/execution/unary/af_arithmetic.bin": "b332ab15", - "webgpu/shader/execution/unary/af_assignment.bin": "9cd4b66", - "webgpu/shader/execution/unary/bool_conversion.bin": "8916fbb", - "webgpu/shader/execution/unary/f16_arithmetic.bin": "5448a82c", - "webgpu/shader/execution/unary/f16_conversion.bin": "1ad05153", - "webgpu/shader/execution/unary/f32_arithmetic.bin": "a2e45ea0", - "webgpu/shader/execution/unary/f32_conversion.bin": "fa062da3", - "webgpu/shader/execution/unary/i32_arithmetic.bin": "2bba8fe4", - "webgpu/shader/execution/unary/i32_complement.bin": "caa954b2", - "webgpu/shader/execution/unary/i32_conversion.bin": "22a36f9e", - "webgpu/shader/execution/unary/u32_complement.bin": "fabf96c0", - "webgpu/shader/execution/unary/u32_conversion.bin": "ec57b500" + "webgpu/shader/execution/binary/af_addition.bin": "5bcc542", + "webgpu/shader/execution/binary/af_logical.bin": "e44143c0", + "webgpu/shader/execution/binary/af_division.bin": "62a4177a", + "webgpu/shader/execution/binary/af_matrix_addition.bin": "a5069db6", + "webgpu/shader/execution/binary/af_matrix_subtraction.bin": "7813d4bc", + "webgpu/shader/execution/binary/af_multiplication.bin": "bb76a321", + "webgpu/shader/execution/binary/af_remainder.bin": "c1095ea1", + "webgpu/shader/execution/binary/af_subtraction.bin": "84d7c81c", + "webgpu/shader/execution/binary/f16_addition.bin": "4ad63c83", + "webgpu/shader/execution/binary/f16_logical.bin": "978dd1ef", + "webgpu/shader/execution/binary/f16_division.bin": "e80548a6", + "webgpu/shader/execution/binary/f16_matrix_addition.bin": "796d135a", + "webgpu/shader/execution/binary/f16_matrix_matrix_multiplication.bin": "c81c7770", + "webgpu/shader/execution/binary/f16_matrix_scalar_multiplication.bin": "adc1bddc", + "webgpu/shader/execution/binary/f16_matrix_subtraction.bin": "e19f2fe", + "webgpu/shader/execution/binary/f16_matrix_vector_multiplication.bin": "535c6b56", + "webgpu/shader/execution/binary/f16_multiplication.bin": "3edc0aa9", + "webgpu/shader/execution/binary/f16_remainder.bin": "2f2492e4", + "webgpu/shader/execution/binary/f16_subtraction.bin": "d9a6b041", + "webgpu/shader/execution/binary/f32_addition.bin": "5fc8796d", + "webgpu/shader/execution/binary/f32_logical.bin": "88c065b6", + "webgpu/shader/execution/binary/f32_division.bin": "38f2e9b6", + "webgpu/shader/execution/binary/f32_matrix_addition.bin": "a0183a6e", + "webgpu/shader/execution/binary/f32_matrix_matrix_multiplication.bin": "27131729", + "webgpu/shader/execution/binary/f32_matrix_scalar_multiplication.bin": "1e60801c", + "webgpu/shader/execution/binary/f32_matrix_subtraction.bin": "999ef3aa", + "webgpu/shader/execution/binary/f32_matrix_vector_multiplication.bin": "4a4544c8", + "webgpu/shader/execution/binary/f32_multiplication.bin": "3cf38e52", + "webgpu/shader/execution/binary/f32_remainder.bin": "a3a1e05c", + "webgpu/shader/execution/binary/f32_subtraction.bin": "f5344626", + "webgpu/shader/execution/binary/i32_arithmetic.bin": "a65d1ba3", + "webgpu/shader/execution/binary/i32_comparison.bin": "65dff959", + "webgpu/shader/execution/binary/u32_arithmetic.bin": "8ca20dc6", + "webgpu/shader/execution/binary/u32_comparison.bin": "29afb233", + "webgpu/shader/execution/abs.bin": "2b89d10a", + "webgpu/shader/execution/acos.bin": "4e088b3a", + "webgpu/shader/execution/acosh.bin": "e0a7c604", + "webgpu/shader/execution/asin.bin": "931b790a", + "webgpu/shader/execution/asinh.bin": "a9026e52", + "webgpu/shader/execution/atan.bin": "299e9e8f", + "webgpu/shader/execution/atan2.bin": "36e31bcc", + "webgpu/shader/execution/atanh.bin": "bc2715ef", + "webgpu/shader/execution/bitcast.bin": "9e97a7eb", + "webgpu/shader/execution/ceil.bin": "fe6b7869", + "webgpu/shader/execution/clamp.bin": "a227d3d2", + "webgpu/shader/execution/cos.bin": "2a991346", + "webgpu/shader/execution/cosh.bin": "ea3c41d8", + "webgpu/shader/execution/cross.bin": "1a1b8321", + "webgpu/shader/execution/degrees.bin": "efd95d31", + "webgpu/shader/execution/determinant.bin": "4325eef9", + "webgpu/shader/execution/distance.bin": "45854a68", + "webgpu/shader/execution/dot.bin": "b06b2ac1", + "webgpu/shader/execution/exp.bin": "9e417842", + "webgpu/shader/execution/exp2.bin": "657559cb", + "webgpu/shader/execution/faceForward.bin": "22e36217", + "webgpu/shader/execution/floor.bin": "4bded93a", + "webgpu/shader/execution/fma.bin": "259e97ec", + "webgpu/shader/execution/fract.bin": "1844053e", + "webgpu/shader/execution/frexp.bin": "795736a4", + "webgpu/shader/execution/inverseSqrt.bin": "39d0ad9d", + "webgpu/shader/execution/ldexp.bin": "9cdba877", + "webgpu/shader/execution/length.bin": "f2971413", + "webgpu/shader/execution/log.bin": "dec7e23a", + "webgpu/shader/execution/log2.bin": "d24dc283", + "webgpu/shader/execution/max.bin": "346e1e88", + "webgpu/shader/execution/min.bin": "2eee31dd", + "webgpu/shader/execution/mix.bin": "7d10c2a9", + "webgpu/shader/execution/modf.bin": "13fff4a7", + "webgpu/shader/execution/normalize.bin": "55f5763b", + "webgpu/shader/execution/pack2x16float.bin": "fc207ec6", + "webgpu/shader/execution/pow.bin": "74f4fe3c", + "webgpu/shader/execution/quantizeToF16.bin": "6f2bf65a", + "webgpu/shader/execution/radians.bin": "3c834c9d", + "webgpu/shader/execution/reflect.bin": "7b87f821", + "webgpu/shader/execution/refract.bin": "e52fa44a", + "webgpu/shader/execution/round.bin": "5d5c72e8", + "webgpu/shader/execution/saturate.bin": "4170af8d", + "webgpu/shader/execution/sign.bin": "e23244e1", + "webgpu/shader/execution/sin.bin": "4a21c66a", + "webgpu/shader/execution/sinh.bin": "e0ed55e8", + "webgpu/shader/execution/smoothstep.bin": "44e4f53b", + "webgpu/shader/execution/sqrt.bin": "bd53552f", + "webgpu/shader/execution/step.bin": "b7dfcc93", + "webgpu/shader/execution/tan.bin": "4a473cc6", + "webgpu/shader/execution/tanh.bin": "45e60ddf", + "webgpu/shader/execution/transpose.bin": "5186fe5b", + "webgpu/shader/execution/trunc.bin": "bfc3ecf9", + "webgpu/shader/execution/unpack2x16float.bin": "302e7cdd", + "webgpu/shader/execution/unpack2x16snorm.bin": "51216313", + "webgpu/shader/execution/unpack2x16unorm.bin": "8bd401b2", + "webgpu/shader/execution/unpack4x8snorm.bin": "4e4985a6", + "webgpu/shader/execution/unpack4x8unorm.bin": "16be9079", + "webgpu/shader/execution/unary/af_arithmetic.bin": "9fd5946a", + "webgpu/shader/execution/unary/af_assignment.bin": "81b91716", + "webgpu/shader/execution/unary/bool_conversion.bin": "699a8913", + "webgpu/shader/execution/unary/f16_arithmetic.bin": "5fedbac9", + "webgpu/shader/execution/unary/f16_conversion.bin": "f05c848d", + "webgpu/shader/execution/unary/f32_arithmetic.bin": "1c0045cc", + "webgpu/shader/execution/unary/f32_conversion.bin": "afa1b58b", + "webgpu/shader/execution/unary/i32_arithmetic.bin": "a996bb97", + "webgpu/shader/execution/unary/i32_complement.bin": "8ba5f8f0", + "webgpu/shader/execution/unary/i32_conversion.bin": "9c7ae9cf", + "webgpu/shader/execution/unary/u32_complement.bin": "b76f5d95", + "webgpu/shader/execution/unary/u32_conversion.bin": "2aaa9ba5" } \ No newline at end of file diff --git a/src/resources/cache/webgpu/shader/execution/acos.bin b/src/resources/cache/webgpu/shader/execution/acos.bin index 34406ee6ff36..a18c5a808b67 100644 Binary files a/src/resources/cache/webgpu/shader/execution/acos.bin and b/src/resources/cache/webgpu/shader/execution/acos.bin differ diff --git a/src/resources/cache/webgpu/shader/execution/acosh.bin b/src/resources/cache/webgpu/shader/execution/acosh.bin index eceb0fcd69a1..a265710f2f03 100644 Binary files a/src/resources/cache/webgpu/shader/execution/acosh.bin and b/src/resources/cache/webgpu/shader/execution/acosh.bin differ diff --git a/src/resources/cache/webgpu/shader/execution/asin.bin b/src/resources/cache/webgpu/shader/execution/asin.bin index 718a766f80a2..b4083247f2ec 100644 Binary files a/src/resources/cache/webgpu/shader/execution/asin.bin and b/src/resources/cache/webgpu/shader/execution/asin.bin differ diff --git a/src/resources/cache/webgpu/shader/execution/atan.bin b/src/resources/cache/webgpu/shader/execution/atan.bin index ca9b4104fa4c..18de2e07afd8 100644 Binary files a/src/resources/cache/webgpu/shader/execution/atan.bin and b/src/resources/cache/webgpu/shader/execution/atan.bin differ diff --git a/src/resources/cache/webgpu/shader/execution/atanh.bin b/src/resources/cache/webgpu/shader/execution/atanh.bin index e5a1e37a594b..2d037ed47664 100644 Binary files a/src/resources/cache/webgpu/shader/execution/atanh.bin and b/src/resources/cache/webgpu/shader/execution/atanh.bin differ diff --git a/src/resources/cache/webgpu/shader/execution/clamp.bin b/src/resources/cache/webgpu/shader/execution/clamp.bin index 7f508d97c3be..772ed8b62bab 100644 Binary files a/src/resources/cache/webgpu/shader/execution/clamp.bin and b/src/resources/cache/webgpu/shader/execution/clamp.bin differ diff --git a/src/resources/cache/webgpu/shader/execution/cos.bin b/src/resources/cache/webgpu/shader/execution/cos.bin index c7b020f58125..2164a1ce49aa 100644 Binary files a/src/resources/cache/webgpu/shader/execution/cos.bin and b/src/resources/cache/webgpu/shader/execution/cos.bin differ diff --git a/src/resources/cache/webgpu/shader/execution/cosh.bin b/src/resources/cache/webgpu/shader/execution/cosh.bin index 010adce0d93a..a4f87d852260 100644 Binary files a/src/resources/cache/webgpu/shader/execution/cosh.bin and b/src/resources/cache/webgpu/shader/execution/cosh.bin differ diff --git a/src/resources/cache/webgpu/shader/execution/degrees.bin b/src/resources/cache/webgpu/shader/execution/degrees.bin index d46206988166..3ef3416aa3c3 100644 Binary files a/src/resources/cache/webgpu/shader/execution/degrees.bin and b/src/resources/cache/webgpu/shader/execution/degrees.bin differ diff --git a/src/resources/cache/webgpu/shader/execution/distance.bin b/src/resources/cache/webgpu/shader/execution/distance.bin index 836ea64173b3..3b7ebdfdfce1 100644 Binary files a/src/resources/cache/webgpu/shader/execution/distance.bin and b/src/resources/cache/webgpu/shader/execution/distance.bin differ diff --git a/src/resources/cache/webgpu/shader/execution/floor.bin b/src/resources/cache/webgpu/shader/execution/floor.bin index 2228293b7547..8641e8596187 100644 Binary files a/src/resources/cache/webgpu/shader/execution/floor.bin and b/src/resources/cache/webgpu/shader/execution/floor.bin differ diff --git a/src/resources/cache/webgpu/shader/execution/fma.bin b/src/resources/cache/webgpu/shader/execution/fma.bin index c73ee5a614ca..ee4d9b9eb14b 100644 Binary files a/src/resources/cache/webgpu/shader/execution/fma.bin and b/src/resources/cache/webgpu/shader/execution/fma.bin differ diff --git a/src/resources/cache/webgpu/shader/execution/fract.bin b/src/resources/cache/webgpu/shader/execution/fract.bin index 3400c36d85a1..6e1bbfd23ba2 100644 Binary files a/src/resources/cache/webgpu/shader/execution/fract.bin and b/src/resources/cache/webgpu/shader/execution/fract.bin differ diff --git a/src/resources/cache/webgpu/shader/execution/frexp.bin b/src/resources/cache/webgpu/shader/execution/frexp.bin index 7ac797f6f447..c4b8abad73bc 100644 Binary files a/src/resources/cache/webgpu/shader/execution/frexp.bin and b/src/resources/cache/webgpu/shader/execution/frexp.bin differ diff --git a/src/resources/cache/webgpu/shader/execution/log.bin b/src/resources/cache/webgpu/shader/execution/log.bin index 9872214a8202..be7b1a07b90e 100644 Binary files a/src/resources/cache/webgpu/shader/execution/log.bin and b/src/resources/cache/webgpu/shader/execution/log.bin differ diff --git a/src/resources/cache/webgpu/shader/execution/log2.bin b/src/resources/cache/webgpu/shader/execution/log2.bin index 703834636b55..b2c4a26a41ac 100644 Binary files a/src/resources/cache/webgpu/shader/execution/log2.bin and b/src/resources/cache/webgpu/shader/execution/log2.bin differ diff --git a/src/resources/cache/webgpu/shader/execution/max.bin b/src/resources/cache/webgpu/shader/execution/max.bin index bf829d7524ab..d88e859e32d1 100644 Binary files a/src/resources/cache/webgpu/shader/execution/max.bin and b/src/resources/cache/webgpu/shader/execution/max.bin differ diff --git a/src/resources/cache/webgpu/shader/execution/min.bin b/src/resources/cache/webgpu/shader/execution/min.bin index a1e8629785c1..fa68f932f493 100644 Binary files a/src/resources/cache/webgpu/shader/execution/min.bin and b/src/resources/cache/webgpu/shader/execution/min.bin differ diff --git a/src/resources/cache/webgpu/shader/execution/mix.bin b/src/resources/cache/webgpu/shader/execution/mix.bin index e1733e50a0a1..35fe1e3ac084 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/resources/cache/webgpu/shader/execution/pow.bin b/src/resources/cache/webgpu/shader/execution/pow.bin index cfa77298b626..c1ffbb0fa59b 100644 Binary files a/src/resources/cache/webgpu/shader/execution/pow.bin and b/src/resources/cache/webgpu/shader/execution/pow.bin differ diff --git a/src/resources/cache/webgpu/shader/execution/radians.bin b/src/resources/cache/webgpu/shader/execution/radians.bin index d410fe26ad4d..baa1cbcc8be8 100644 Binary files a/src/resources/cache/webgpu/shader/execution/radians.bin and b/src/resources/cache/webgpu/shader/execution/radians.bin differ diff --git a/src/resources/cache/webgpu/shader/execution/sign.bin b/src/resources/cache/webgpu/shader/execution/sign.bin index 94e68bcdfa8b..fee195390e79 100644 Binary files a/src/resources/cache/webgpu/shader/execution/sign.bin and b/src/resources/cache/webgpu/shader/execution/sign.bin differ diff --git a/src/resources/cache/webgpu/shader/execution/sin.bin b/src/resources/cache/webgpu/shader/execution/sin.bin index 4f52e1adb384..2c74717a4319 100644 Binary files a/src/resources/cache/webgpu/shader/execution/sin.bin and b/src/resources/cache/webgpu/shader/execution/sin.bin differ diff --git a/src/resources/cache/webgpu/shader/execution/sinh.bin b/src/resources/cache/webgpu/shader/execution/sinh.bin index b3f7f01b356f..8ce8d89c4af9 100644 Binary files a/src/resources/cache/webgpu/shader/execution/sinh.bin and b/src/resources/cache/webgpu/shader/execution/sinh.bin differ diff --git a/src/resources/cache/webgpu/shader/execution/smoothstep.bin b/src/resources/cache/webgpu/shader/execution/smoothstep.bin index 86f73362dd04..8481527696b6 100644 Binary files a/src/resources/cache/webgpu/shader/execution/smoothstep.bin and b/src/resources/cache/webgpu/shader/execution/smoothstep.bin differ diff --git a/src/resources/cache/webgpu/shader/execution/sqrt.bin b/src/resources/cache/webgpu/shader/execution/sqrt.bin index 0dd7a2ac5f72..6778436fc63a 100644 Binary files a/src/resources/cache/webgpu/shader/execution/sqrt.bin and b/src/resources/cache/webgpu/shader/execution/sqrt.bin differ diff --git a/src/resources/cache/webgpu/shader/execution/trunc.bin b/src/resources/cache/webgpu/shader/execution/trunc.bin index 193a90a78d65..2b49373ba078 100644 Binary files a/src/resources/cache/webgpu/shader/execution/trunc.bin and b/src/resources/cache/webgpu/shader/execution/trunc.bin differ diff --git a/src/unittests/maths.spec.ts b/src/unittests/maths.spec.ts index 357c574281f3..6b95ca0ea8d4 100644 --- a/src/unittests/maths.spec.ts +++ b/src/unittests/maths.spec.ts @@ -22,8 +22,8 @@ import { correctlyRoundedF32, FlushMode, frexp, - fullF16Range, - fullF32Range, + scalarF16Range, + scalarF32Range, fullI32Range, lerp, linearRange, @@ -1557,7 +1557,7 @@ g.test('fullF32Range') const neg_sub = test.params.neg_sub; const pos_sub = test.params.pos_sub; const pos_norm = test.params.pos_norm; - const got = fullF32Range({ neg_norm, neg_sub, pos_sub, pos_norm }); + const got = scalarF32Range({ neg_norm, neg_sub, pos_sub, pos_norm }); const expect = test.params.expect; test.expect( @@ -1598,7 +1598,7 @@ g.test('fullF16Range') const neg_sub = test.params.neg_sub; const pos_sub = test.params.pos_sub; const pos_norm = test.params.pos_norm; - const got = fullF16Range({ neg_norm, neg_sub, pos_sub, pos_norm }); + const got = scalarF16Range({ neg_norm, neg_sub, pos_sub, pos_norm }); const expect = test.params.expect; test.expect( diff --git a/src/webgpu/shader/execution/expression/binary/af_addition.spec.ts b/src/webgpu/shader/execution/expression/binary/af_addition.spec.ts index 0f703f088970..29fb42e386b0 100644 --- a/src/webgpu/shader/execution/expression/binary/af_addition.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/af_addition.spec.ts @@ -6,7 +6,7 @@ import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; import { TypeAbstractFloat, TypeVec } from '../../../../util/conversion.js'; import { FP, FPVector } from '../../../../util/floating_point.js'; -import { sparseF64Range, sparseVectorF64Range } from '../../../../util/math.js'; +import { sparseScalarF64Range, sparseVectorF64Range } from '../../../../util/math.js'; import { makeCaseCache } from '../case_cache.js'; import { onlyConstInputSource, run } from '../expression.js'; @@ -25,8 +25,8 @@ export const g = makeTestGroup(GPUTest); const scalar_cases = { ['scalar']: () => { return FP.abstract.generateScalarPairToIntervalCases( - sparseF64Range(), - sparseF64Range(), + sparseScalarF64Range(), + sparseScalarF64Range(), 'finite', FP.abstract.additionInterval ); @@ -38,7 +38,7 @@ const vector_scalar_cases = ([2, 3, 4] as const) [`vec${dim}_scalar`]: () => { return FP.abstract.generateVectorScalarToVectorCases( sparseVectorF64Range(dim), - sparseF64Range(), + sparseScalarF64Range(), 'finite', additionVectorScalarInterval ); @@ -50,7 +50,7 @@ const scalar_vector_cases = ([2, 3, 4] as const) .map(dim => ({ [`scalar_vec${dim}`]: () => { return FP.abstract.generateScalarVectorToVectorCases( - sparseF64Range(), + sparseScalarF64Range(), sparseVectorF64Range(dim), 'finite', additionScalarVectorInterval diff --git a/src/webgpu/shader/execution/expression/binary/af_division.spec.ts b/src/webgpu/shader/execution/expression/binary/af_division.spec.ts index 4c1765d20337..6b2cd819f4ee 100644 --- a/src/webgpu/shader/execution/expression/binary/af_division.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/af_division.spec.ts @@ -6,7 +6,7 @@ import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; import { TypeAbstractFloat, TypeVec } from '../../../../util/conversion.js'; import { FP, FPVector } from '../../../../util/floating_point.js'; -import { sparseF64Range, sparseVectorF64Range } from '../../../../util/math.js'; +import { sparseScalarF64Range, sparseVectorF64Range } from '../../../../util/math.js'; import { makeCaseCache } from '../case_cache.js'; import { onlyConstInputSource, run } from '../expression.js'; @@ -25,8 +25,8 @@ export const g = makeTestGroup(GPUTest); const scalar_cases = { ['scalar']: () => { return FP.abstract.generateScalarPairToIntervalCases( - sparseF64Range(), - sparseF64Range(), + sparseScalarF64Range(), + sparseScalarF64Range(), 'finite', FP.abstract.divisionInterval ); @@ -38,7 +38,7 @@ const vector_scalar_cases = ([2, 3, 4] as const) [`vec${dim}_scalar`]: () => { return FP.abstract.generateVectorScalarToVectorCases( sparseVectorF64Range(dim), - sparseF64Range(), + sparseScalarF64Range(), 'finite', divisionVectorScalarInterval ); @@ -50,7 +50,7 @@ const scalar_vector_cases = ([2, 3, 4] as const) .map(dim => ({ [`scalar_vec${dim}`]: () => { return FP.abstract.generateScalarVectorToVectorCases( - sparseF64Range(), + sparseScalarF64Range(), sparseVectorF64Range(dim), 'finite', divisionScalarVectorInterval diff --git a/src/webgpu/shader/execution/expression/binary/af_multiplication.spec.ts b/src/webgpu/shader/execution/expression/binary/af_multiplication.spec.ts index 6b1581270346..61626203b8b7 100644 --- a/src/webgpu/shader/execution/expression/binary/af_multiplication.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/af_multiplication.spec.ts @@ -6,7 +6,7 @@ import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; import { TypeAbstractFloat, TypeVec } from '../../../../util/conversion.js'; import { FP, FPVector } from '../../../../util/floating_point.js'; -import { sparseF64Range, sparseVectorF64Range } from '../../../../util/math.js'; +import { sparseScalarF64Range, sparseVectorF64Range } from '../../../../util/math.js'; import { makeCaseCache } from '../case_cache.js'; import { onlyConstInputSource, run } from '../expression.js'; @@ -25,8 +25,8 @@ export const g = makeTestGroup(GPUTest); const scalar_cases = { ['scalar']: () => { return FP.abstract.generateScalarPairToIntervalCases( - sparseF64Range(), - sparseF64Range(), + sparseScalarF64Range(), + sparseScalarF64Range(), 'finite', FP.abstract.multiplicationInterval ); @@ -38,7 +38,7 @@ const vector_scalar_cases = ([2, 3, 4] as const) [`vec${dim}_scalar`]: () => { return FP.abstract.generateVectorScalarToVectorCases( sparseVectorF64Range(dim), - sparseF64Range(), + sparseScalarF64Range(), 'finite', multiplicationVectorScalarInterval ); @@ -50,7 +50,7 @@ const scalar_vector_cases = ([2, 3, 4] as const) .map(dim => ({ [`scalar_vec${dim}`]: () => { return FP.abstract.generateScalarVectorToVectorCases( - sparseF64Range(), + sparseScalarF64Range(), sparseVectorF64Range(dim), 'finite', multiplicationScalarVectorInterval diff --git a/src/webgpu/shader/execution/expression/binary/af_remainder.spec.ts b/src/webgpu/shader/execution/expression/binary/af_remainder.spec.ts index b4ce930bdb25..12002e867747 100644 --- a/src/webgpu/shader/execution/expression/binary/af_remainder.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/af_remainder.spec.ts @@ -6,7 +6,7 @@ import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; import { TypeAbstractFloat, TypeVec } from '../../../../util/conversion.js'; import { FP, FPVector } from '../../../../util/floating_point.js'; -import { sparseF64Range, sparseVectorF64Range } from '../../../../util/math.js'; +import { sparseScalarF64Range, sparseVectorF64Range } from '../../../../util/math.js'; import { makeCaseCache } from '../case_cache.js'; import { onlyConstInputSource, run } from '../expression.js'; @@ -25,8 +25,8 @@ export const g = makeTestGroup(GPUTest); const scalar_cases = { ['scalar']: () => { return FP.abstract.generateScalarPairToIntervalCases( - sparseF64Range(), - sparseF64Range(), + sparseScalarF64Range(), + sparseScalarF64Range(), 'finite', FP.abstract.remainderInterval ); @@ -38,7 +38,7 @@ const vector_scalar_cases = ([2, 3, 4] as const) [`vec${dim}_scalar`]: () => { return FP.abstract.generateVectorScalarToVectorCases( sparseVectorF64Range(dim), - sparseF64Range(), + sparseScalarF64Range(), 'finite', remainderVectorScalarInterval ); @@ -50,7 +50,7 @@ const scalar_vector_cases = ([2, 3, 4] as const) .map(dim => ({ [`scalar_vec${dim}`]: () => { return FP.abstract.generateScalarVectorToVectorCases( - sparseF64Range(), + sparseScalarF64Range(), sparseVectorF64Range(dim), 'finite', remainderScalarVectorInterval diff --git a/src/webgpu/shader/execution/expression/binary/af_subtraction.spec.ts b/src/webgpu/shader/execution/expression/binary/af_subtraction.spec.ts index 00dc66feb951..09617a6379a8 100644 --- a/src/webgpu/shader/execution/expression/binary/af_subtraction.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/af_subtraction.spec.ts @@ -6,7 +6,7 @@ import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; import { TypeAbstractFloat, TypeVec } from '../../../../util/conversion.js'; import { FP, FPVector } from '../../../../util/floating_point.js'; -import { sparseF64Range, sparseVectorF64Range } from '../../../../util/math.js'; +import { sparseScalarF64Range, sparseVectorF64Range } from '../../../../util/math.js'; import { makeCaseCache } from '../case_cache.js'; import { onlyConstInputSource, run } from '../expression.js'; @@ -25,8 +25,8 @@ export const g = makeTestGroup(GPUTest); const scalar_cases = { ['scalar']: () => { return FP.abstract.generateScalarPairToIntervalCases( - sparseF64Range(), - sparseF64Range(), + sparseScalarF64Range(), + sparseScalarF64Range(), 'finite', FP.abstract.subtractionInterval ); @@ -38,7 +38,7 @@ const vector_scalar_cases = ([2, 3, 4] as const) [`vec${dim}_scalar`]: () => { return FP.abstract.generateVectorScalarToVectorCases( sparseVectorF64Range(dim), - sparseF64Range(), + sparseScalarF64Range(), 'finite', subtractionVectorScalarInterval ); @@ -50,7 +50,7 @@ const scalar_vector_cases = ([2, 3, 4] as const) .map(dim => ({ [`scalar_vec${dim}`]: () => { return FP.abstract.generateScalarVectorToVectorCases( - sparseF64Range(), + sparseScalarF64Range(), sparseVectorF64Range(dim), 'finite', subtractionScalarVectorInterval diff --git a/src/webgpu/shader/execution/expression/binary/f16_addition.spec.ts b/src/webgpu/shader/execution/expression/binary/f16_addition.spec.ts index 8948f9049963..99c08db43681 100644 --- a/src/webgpu/shader/execution/expression/binary/f16_addition.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/f16_addition.spec.ts @@ -6,7 +6,7 @@ import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; import { TypeF16, TypeVec } from '../../../../util/conversion.js'; import { FP, FPVector } from '../../../../util/floating_point.js'; -import { sparseF16Range, sparseVectorF16Range } from '../../../../util/math.js'; +import { sparseScalarF16Range, sparseVectorF16Range } from '../../../../util/math.js'; import { makeCaseCache } from '../case_cache.js'; import { allInputSources, run } from '../expression.js'; @@ -26,8 +26,8 @@ const scalar_cases = ([true, false] as const) .map(nonConst => ({ [`scalar_${nonConst ? 'non_const' : 'const'}`]: () => { return FP.f16.generateScalarPairToIntervalCases( - sparseF16Range(), - sparseF16Range(), + sparseScalarF16Range(), + sparseScalarF16Range(), nonConst ? 'unfiltered' : 'finite', FP.f16.additionInterval ); @@ -41,7 +41,7 @@ const vector_scalar_cases = ([2, 3, 4] as const) [`vec${dim}_scalar_${nonConst ? 'non_const' : 'const'}`]: () => { return FP.f16.generateVectorScalarToVectorCases( sparseVectorF16Range(dim), - sparseF16Range(), + sparseScalarF16Range(), nonConst ? 'unfiltered' : 'finite', additionVectorScalarInterval ); @@ -55,7 +55,7 @@ const scalar_vector_cases = ([2, 3, 4] as const) ([true, false] as const).map(nonConst => ({ [`scalar_vec${dim}_${nonConst ? 'non_const' : 'const'}`]: () => { return FP.f16.generateScalarVectorToVectorCases( - sparseF16Range(), + sparseScalarF16Range(), sparseVectorF16Range(dim), nonConst ? 'unfiltered' : 'finite', additionScalarVectorInterval diff --git a/src/webgpu/shader/execution/expression/binary/f16_division.spec.ts b/src/webgpu/shader/execution/expression/binary/f16_division.spec.ts index c3b8fc04dbb7..725c90828071 100644 --- a/src/webgpu/shader/execution/expression/binary/f16_division.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/f16_division.spec.ts @@ -6,7 +6,7 @@ import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; import { TypeF16, TypeVec } from '../../../../util/conversion.js'; import { FP, FPVector } from '../../../../util/floating_point.js'; -import { sparseF16Range, sparseVectorF16Range } from '../../../../util/math.js'; +import { sparseScalarF16Range, sparseVectorF16Range } from '../../../../util/math.js'; import { makeCaseCache } from '../case_cache.js'; import { allInputSources, run } from '../expression.js'; @@ -26,8 +26,8 @@ const scalar_cases = ([true, false] as const) .map(nonConst => ({ [`scalar_${nonConst ? 'non_const' : 'const'}`]: () => { return FP.f16.generateScalarPairToIntervalCases( - sparseF16Range(), - sparseF16Range(), + sparseScalarF16Range(), + sparseScalarF16Range(), nonConst ? 'unfiltered' : 'finite', FP.f16.divisionInterval ); @@ -41,7 +41,7 @@ const vector_scalar_cases = ([2, 3, 4] as const) [`vec${dim}_scalar_${nonConst ? 'non_const' : 'const'}`]: () => { return FP.f16.generateVectorScalarToVectorCases( sparseVectorF16Range(dim), - sparseF16Range(), + sparseScalarF16Range(), nonConst ? 'unfiltered' : 'finite', divisionVectorScalarInterval ); @@ -55,7 +55,7 @@ const scalar_vector_cases = ([2, 3, 4] as const) ([true, false] as const).map(nonConst => ({ [`scalar_vec${dim}_${nonConst ? 'non_const' : 'const'}`]: () => { return FP.f16.generateScalarVectorToVectorCases( - sparseF16Range(), + sparseScalarF16Range(), sparseVectorF16Range(dim), nonConst ? 'unfiltered' : 'finite', divisionScalarVectorInterval diff --git a/src/webgpu/shader/execution/expression/binary/f16_matrix_scalar_multiplication.spec.ts b/src/webgpu/shader/execution/expression/binary/f16_matrix_scalar_multiplication.spec.ts index 29d4700ee69e..83f583f9b6d7 100644 --- a/src/webgpu/shader/execution/expression/binary/f16_matrix_scalar_multiplication.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/f16_matrix_scalar_multiplication.spec.ts @@ -6,7 +6,7 @@ import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; import { TypeF16, TypeMat } from '../../../../util/conversion.js'; import { FP } from '../../../../util/floating_point.js'; -import { sparseF16Range, sparseMatrixF16Range } from '../../../../util/math.js'; +import { sparseScalarF16Range, sparseMatrixF16Range } from '../../../../util/math.js'; import { makeCaseCache } from '../case_cache.js'; import { allInputSources, run } from '../expression.js'; @@ -22,7 +22,7 @@ const mat_scalar_cases = ([2, 3, 4] as const) [`mat${cols}x${rows}_scalar_${nonConst ? 'non_const' : 'const'}`]: () => { return FP.f16.generateMatrixScalarToMatrixCases( sparseMatrixF16Range(cols, rows), - sparseF16Range(), + sparseScalarF16Range(), nonConst ? 'unfiltered' : 'finite', FP.f16.multiplicationMatrixScalarInterval ); @@ -39,7 +39,7 @@ const scalar_mat_cases = ([2, 3, 4] as const) ([true, false] as const).map(nonConst => ({ [`scalar_mat${cols}x${rows}_${nonConst ? 'non_const' : 'const'}`]: () => { return FP.f16.generateScalarMatrixToMatrixCases( - sparseF16Range(), + sparseScalarF16Range(), sparseMatrixF16Range(cols, rows), nonConst ? 'unfiltered' : 'finite', FP.f16.multiplicationScalarMatrixInterval diff --git a/src/webgpu/shader/execution/expression/binary/f16_multiplication.spec.ts b/src/webgpu/shader/execution/expression/binary/f16_multiplication.spec.ts index 10041fbc173f..9af0c2918aa4 100644 --- a/src/webgpu/shader/execution/expression/binary/f16_multiplication.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/f16_multiplication.spec.ts @@ -6,7 +6,7 @@ import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; import { TypeF16, TypeVec } from '../../../../util/conversion.js'; import { FP, FPVector } from '../../../../util/floating_point.js'; -import { sparseF16Range, sparseVectorF16Range } from '../../../../util/math.js'; +import { sparseScalarF16Range, sparseVectorF16Range } from '../../../../util/math.js'; import { makeCaseCache } from '../case_cache.js'; import { allInputSources, run } from '../expression.js'; @@ -26,8 +26,8 @@ const scalar_cases = ([true, false] as const) .map(nonConst => ({ [`scalar_${nonConst ? 'non_const' : 'const'}`]: () => { return FP.f16.generateScalarPairToIntervalCases( - sparseF16Range(), - sparseF16Range(), + sparseScalarF16Range(), + sparseScalarF16Range(), nonConst ? 'unfiltered' : 'finite', FP.f16.multiplicationInterval ); @@ -41,7 +41,7 @@ const vector_scalar_cases = ([2, 3, 4] as const) [`vec${dim}_scalar_${nonConst ? 'non_const' : 'const'}`]: () => { return FP.f16.generateVectorScalarToVectorCases( sparseVectorF16Range(dim), - sparseF16Range(), + sparseScalarF16Range(), nonConst ? 'unfiltered' : 'finite', multiplicationVectorScalarInterval ); @@ -55,7 +55,7 @@ const scalar_vector_cases = ([2, 3, 4] as const) ([true, false] as const).map(nonConst => ({ [`scalar_vec${dim}_${nonConst ? 'non_const' : 'const'}`]: () => { return FP.f16.generateScalarVectorToVectorCases( - sparseF16Range(), + sparseScalarF16Range(), sparseVectorF16Range(dim), nonConst ? 'unfiltered' : 'finite', multiplicationScalarVectorInterval diff --git a/src/webgpu/shader/execution/expression/binary/f16_remainder.spec.ts b/src/webgpu/shader/execution/expression/binary/f16_remainder.spec.ts index 801b84904b84..e7f10daf4eb8 100644 --- a/src/webgpu/shader/execution/expression/binary/f16_remainder.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/f16_remainder.spec.ts @@ -6,7 +6,7 @@ import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; import { TypeF16, TypeVec } from '../../../../util/conversion.js'; import { FP, FPVector } from '../../../../util/floating_point.js'; -import { sparseF16Range, sparseVectorF16Range } from '../../../../util/math.js'; +import { sparseScalarF16Range, sparseVectorF16Range } from '../../../../util/math.js'; import { makeCaseCache } from '../case_cache.js'; import { allInputSources, run } from '../expression.js'; @@ -26,8 +26,8 @@ const scalar_cases = ([true, false] as const) .map(nonConst => ({ [`scalar_${nonConst ? 'non_const' : 'const'}`]: () => { return FP.f16.generateScalarPairToIntervalCases( - sparseF16Range(), - sparseF16Range(), + sparseScalarF16Range(), + sparseScalarF16Range(), nonConst ? 'unfiltered' : 'finite', FP.f16.remainderInterval ); @@ -41,7 +41,7 @@ const vector_scalar_cases = ([2, 3, 4] as const) [`vec${dim}_scalar_${nonConst ? 'non_const' : 'const'}`]: () => { return FP.f16.generateVectorScalarToVectorCases( sparseVectorF16Range(dim), - sparseF16Range(), + sparseScalarF16Range(), nonConst ? 'unfiltered' : 'finite', remainderVectorScalarInterval ); @@ -55,7 +55,7 @@ const scalar_vector_cases = ([2, 3, 4] as const) ([true, false] as const).map(nonConst => ({ [`scalar_vec${dim}_${nonConst ? 'non_const' : 'const'}`]: () => { return FP.f16.generateScalarVectorToVectorCases( - sparseF16Range(), + sparseScalarF16Range(), sparseVectorF16Range(dim), nonConst ? 'unfiltered' : 'finite', remainderScalarVectorInterval diff --git a/src/webgpu/shader/execution/expression/binary/f16_subtraction.spec.ts b/src/webgpu/shader/execution/expression/binary/f16_subtraction.spec.ts index a64d5568375f..923c95d40108 100644 --- a/src/webgpu/shader/execution/expression/binary/f16_subtraction.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/f16_subtraction.spec.ts @@ -6,7 +6,7 @@ import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; import { TypeF16, TypeVec } from '../../../../util/conversion.js'; import { FP, FPVector } from '../../../../util/floating_point.js'; -import { sparseF16Range, sparseVectorF16Range } from '../../../../util/math.js'; +import { sparseScalarF16Range, sparseVectorF16Range } from '../../../../util/math.js'; import { makeCaseCache } from '../case_cache.js'; import { allInputSources, run } from '../expression.js'; @@ -26,8 +26,8 @@ const scalar_cases = ([true, false] as const) .map(nonConst => ({ [`scalar_${nonConst ? 'non_const' : 'const'}`]: () => { return FP.f16.generateScalarPairToIntervalCases( - sparseF16Range(), - sparseF16Range(), + sparseScalarF16Range(), + sparseScalarF16Range(), nonConst ? 'unfiltered' : 'finite', FP.f16.subtractionInterval ); @@ -41,7 +41,7 @@ const vector_scalar_cases = ([2, 3, 4] as const) [`vec${dim}_scalar_${nonConst ? 'non_const' : 'const'}`]: () => { return FP.f16.generateVectorScalarToVectorCases( sparseVectorF16Range(dim), - sparseF16Range(), + sparseScalarF16Range(), nonConst ? 'unfiltered' : 'finite', subtractionVectorScalarInterval ); @@ -55,7 +55,7 @@ const scalar_vector_cases = ([2, 3, 4] as const) ([true, false] as const).map(nonConst => ({ [`scalar_vec${dim}_${nonConst ? 'non_const' : 'const'}`]: () => { return FP.f16.generateScalarVectorToVectorCases( - sparseF16Range(), + sparseScalarF16Range(), sparseVectorF16Range(dim), nonConst ? 'unfiltered' : 'finite', subtractionScalarVectorInterval diff --git a/src/webgpu/shader/execution/expression/binary/f32_addition.spec.ts b/src/webgpu/shader/execution/expression/binary/f32_addition.spec.ts index 65739f67ca6c..772ec272e93f 100644 --- a/src/webgpu/shader/execution/expression/binary/f32_addition.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/f32_addition.spec.ts @@ -6,7 +6,7 @@ import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; import { TypeF32, TypeVec } from '../../../../util/conversion.js'; import { FP, FPVector } from '../../../../util/floating_point.js'; -import { sparseF32Range, sparseVectorF32Range } from '../../../../util/math.js'; +import { sparseScalarF32Range, sparseVectorF32Range } from '../../../../util/math.js'; import { makeCaseCache } from '../case_cache.js'; import { allInputSources, run } from '../expression.js'; @@ -26,8 +26,8 @@ const scalar_cases = ([true, false] as const) .map(nonConst => ({ [`scalar_${nonConst ? 'non_const' : 'const'}`]: () => { return FP.f32.generateScalarPairToIntervalCases( - sparseF32Range(), - sparseF32Range(), + sparseScalarF32Range(), + sparseScalarF32Range(), nonConst ? 'unfiltered' : 'finite', FP.f32.additionInterval ); @@ -41,7 +41,7 @@ const vector_scalar_cases = ([2, 3, 4] as const) [`vec${dim}_scalar_${nonConst ? 'non_const' : 'const'}`]: () => { return FP.f32.generateVectorScalarToVectorCases( sparseVectorF32Range(dim), - sparseF32Range(), + sparseScalarF32Range(), nonConst ? 'unfiltered' : 'finite', additionVectorScalarInterval ); @@ -55,7 +55,7 @@ const scalar_vector_cases = ([2, 3, 4] as const) ([true, false] as const).map(nonConst => ({ [`scalar_vec${dim}_${nonConst ? 'non_const' : 'const'}`]: () => { return FP.f32.generateScalarVectorToVectorCases( - sparseF32Range(), + sparseScalarF32Range(), sparseVectorF32Range(dim), nonConst ? 'unfiltered' : 'finite', additionScalarVectorInterval diff --git a/src/webgpu/shader/execution/expression/binary/f32_division.spec.ts b/src/webgpu/shader/execution/expression/binary/f32_division.spec.ts index bd3793bf8a66..ecbf7e4fd7dc 100644 --- a/src/webgpu/shader/execution/expression/binary/f32_division.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/f32_division.spec.ts @@ -6,7 +6,7 @@ import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; import { TypeF32, TypeVec } from '../../../../util/conversion.js'; import { FP, FPVector } from '../../../../util/floating_point.js'; -import { sparseF32Range, sparseVectorF32Range } from '../../../../util/math.js'; +import { sparseScalarF32Range, sparseVectorF32Range } from '../../../../util/math.js'; import { makeCaseCache } from '../case_cache.js'; import { allInputSources, run } from '../expression.js'; @@ -26,8 +26,8 @@ const scalar_cases = ([true, false] as const) .map(nonConst => ({ [`scalar_${nonConst ? 'non_const' : 'const'}`]: () => { return FP.f32.generateScalarPairToIntervalCases( - sparseF32Range(), - sparseF32Range(), + sparseScalarF32Range(), + sparseScalarF32Range(), nonConst ? 'unfiltered' : 'finite', FP.f32.divisionInterval ); @@ -41,7 +41,7 @@ const vector_scalar_cases = ([2, 3, 4] as const) [`vec${dim}_scalar_${nonConst ? 'non_const' : 'const'}`]: () => { return FP.f32.generateVectorScalarToVectorCases( sparseVectorF32Range(dim), - sparseF32Range(), + sparseScalarF32Range(), nonConst ? 'unfiltered' : 'finite', divisionVectorScalarInterval ); @@ -55,7 +55,7 @@ const scalar_vector_cases = ([2, 3, 4] as const) ([true, false] as const).map(nonConst => ({ [`scalar_vec${dim}_${nonConst ? 'non_const' : 'const'}`]: () => { return FP.f32.generateScalarVectorToVectorCases( - sparseF32Range(), + sparseScalarF32Range(), sparseVectorF32Range(dim), nonConst ? 'unfiltered' : 'finite', divisionScalarVectorInterval diff --git a/src/webgpu/shader/execution/expression/binary/f32_matrix_scalar_multiplication.spec.ts b/src/webgpu/shader/execution/expression/binary/f32_matrix_scalar_multiplication.spec.ts index f3d36b83828a..8f50c7781688 100644 --- a/src/webgpu/shader/execution/expression/binary/f32_matrix_scalar_multiplication.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/f32_matrix_scalar_multiplication.spec.ts @@ -6,7 +6,7 @@ import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; import { TypeF32, TypeMat } from '../../../../util/conversion.js'; import { FP } from '../../../../util/floating_point.js'; -import { sparseF32Range, sparseMatrixF32Range } from '../../../../util/math.js'; +import { sparseScalarF32Range, sparseMatrixF32Range } from '../../../../util/math.js'; import { makeCaseCache } from '../case_cache.js'; import { allInputSources, run } from '../expression.js'; @@ -22,7 +22,7 @@ const mat_scalar_cases = ([2, 3, 4] as const) [`mat${cols}x${rows}_scalar_${nonConst ? 'non_const' : 'const'}`]: () => { return FP.f32.generateMatrixScalarToMatrixCases( sparseMatrixF32Range(cols, rows), - sparseF32Range(), + sparseScalarF32Range(), nonConst ? 'unfiltered' : 'finite', FP.f32.multiplicationMatrixScalarInterval ); @@ -39,7 +39,7 @@ const scalar_mat_cases = ([2, 3, 4] as const) ([true, false] as const).map(nonConst => ({ [`scalar_mat${cols}x${rows}_${nonConst ? 'non_const' : 'const'}`]: () => { return FP.f32.generateScalarMatrixToMatrixCases( - sparseF32Range(), + sparseScalarF32Range(), sparseMatrixF32Range(cols, rows), nonConst ? 'unfiltered' : 'finite', FP.f32.multiplicationScalarMatrixInterval diff --git a/src/webgpu/shader/execution/expression/binary/f32_multiplication.spec.ts b/src/webgpu/shader/execution/expression/binary/f32_multiplication.spec.ts index 38da08fd3e77..1c0da8ed19f5 100644 --- a/src/webgpu/shader/execution/expression/binary/f32_multiplication.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/f32_multiplication.spec.ts @@ -6,7 +6,7 @@ import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; import { TypeF32, TypeVec } from '../../../../util/conversion.js'; import { FP, FPVector } from '../../../../util/floating_point.js'; -import { sparseF32Range, sparseVectorF32Range } from '../../../../util/math.js'; +import { sparseScalarF32Range, sparseVectorF32Range } from '../../../../util/math.js'; import { makeCaseCache } from '../case_cache.js'; import { allInputSources, run } from '../expression.js'; @@ -26,8 +26,8 @@ const scalar_cases = ([true, false] as const) .map(nonConst => ({ [`scalar_${nonConst ? 'non_const' : 'const'}`]: () => { return FP.f32.generateScalarPairToIntervalCases( - sparseF32Range(), - sparseF32Range(), + sparseScalarF32Range(), + sparseScalarF32Range(), nonConst ? 'unfiltered' : 'finite', FP.f32.multiplicationInterval ); @@ -41,7 +41,7 @@ const vector_scalar_cases = ([2, 3, 4] as const) [`vec${dim}_scalar_${nonConst ? 'non_const' : 'const'}`]: () => { return FP.f32.generateVectorScalarToVectorCases( sparseVectorF32Range(dim), - sparseF32Range(), + sparseScalarF32Range(), nonConst ? 'unfiltered' : 'finite', multiplicationVectorScalarInterval ); @@ -55,7 +55,7 @@ const scalar_vector_cases = ([2, 3, 4] as const) ([true, false] as const).map(nonConst => ({ [`scalar_vec${dim}_${nonConst ? 'non_const' : 'const'}`]: () => { return FP.f32.generateScalarVectorToVectorCases( - sparseF32Range(), + sparseScalarF32Range(), sparseVectorF32Range(dim), nonConst ? 'unfiltered' : 'finite', multiplicationScalarVectorInterval diff --git a/src/webgpu/shader/execution/expression/binary/f32_remainder.spec.ts b/src/webgpu/shader/execution/expression/binary/f32_remainder.spec.ts index 390a7f34266c..3add756dfd66 100644 --- a/src/webgpu/shader/execution/expression/binary/f32_remainder.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/f32_remainder.spec.ts @@ -6,7 +6,7 @@ import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; import { TypeF32, TypeVec } from '../../../../util/conversion.js'; import { FP, FPVector } from '../../../../util/floating_point.js'; -import { sparseF32Range, sparseVectorF32Range } from '../../../../util/math.js'; +import { sparseScalarF32Range, sparseVectorF32Range } from '../../../../util/math.js'; import { makeCaseCache } from '../case_cache.js'; import { allInputSources, run } from '../expression.js'; @@ -26,8 +26,8 @@ const scalar_cases = ([true, false] as const) .map(nonConst => ({ [`scalar_${nonConst ? 'non_const' : 'const'}`]: () => { return FP.f32.generateScalarPairToIntervalCases( - sparseF32Range(), - sparseF32Range(), + sparseScalarF32Range(), + sparseScalarF32Range(), nonConst ? 'unfiltered' : 'finite', FP.f32.remainderInterval ); @@ -41,7 +41,7 @@ const vector_scalar_cases = ([2, 3, 4] as const) [`vec${dim}_scalar_${nonConst ? 'non_const' : 'const'}`]: () => { return FP.f32.generateVectorScalarToVectorCases( sparseVectorF32Range(dim), - sparseF32Range(), + sparseScalarF32Range(), nonConst ? 'unfiltered' : 'finite', remainderVectorScalarInterval ); @@ -55,7 +55,7 @@ const scalar_vector_cases = ([2, 3, 4] as const) ([true, false] as const).map(nonConst => ({ [`scalar_vec${dim}_${nonConst ? 'non_const' : 'const'}`]: () => { return FP.f32.generateScalarVectorToVectorCases( - sparseF32Range(), + sparseScalarF32Range(), sparseVectorF32Range(dim), nonConst ? 'unfiltered' : 'finite', remainderScalarVectorInterval diff --git a/src/webgpu/shader/execution/expression/binary/f32_subtraction.spec.ts b/src/webgpu/shader/execution/expression/binary/f32_subtraction.spec.ts index 91e06b7de8c1..2870a14177b7 100644 --- a/src/webgpu/shader/execution/expression/binary/f32_subtraction.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/f32_subtraction.spec.ts @@ -6,7 +6,7 @@ import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; import { TypeF32, TypeVec } from '../../../../util/conversion.js'; import { FP, FPVector } from '../../../../util/floating_point.js'; -import { sparseF32Range, sparseVectorF32Range } from '../../../../util/math.js'; +import { sparseScalarF32Range, sparseVectorF32Range } from '../../../../util/math.js'; import { makeCaseCache } from '../case_cache.js'; import { allInputSources, run } from '../expression.js'; @@ -26,8 +26,8 @@ const scalar_cases = ([true, false] as const) .map(nonConst => ({ [`scalar_${nonConst ? 'non_const' : 'const'}`]: () => { return FP.f32.generateScalarPairToIntervalCases( - sparseF32Range(), - sparseF32Range(), + sparseScalarF32Range(), + sparseScalarF32Range(), nonConst ? 'unfiltered' : 'finite', FP.f32.subtractionInterval ); @@ -41,7 +41,7 @@ const vector_scalar_cases = ([2, 3, 4] as const) [`vec${dim}_scalar_${nonConst ? 'non_const' : 'const'}`]: () => { return FP.f32.generateVectorScalarToVectorCases( sparseVectorF32Range(dim), - sparseF32Range(), + sparseScalarF32Range(), nonConst ? 'unfiltered' : 'finite', subtractionVectorScalarInterval ); @@ -55,7 +55,7 @@ const scalar_vector_cases = ([2, 3, 4] as const) ([true, false] as const).map(nonConst => ({ [`scalar_vec${dim}_${nonConst ? 'non_const' : 'const'}`]: () => { return FP.f32.generateScalarVectorToVectorCases( - sparseF32Range(), + sparseScalarF32Range(), sparseVectorF32Range(dim), nonConst ? 'unfiltered' : 'finite', subtractionScalarVectorInterval diff --git a/src/webgpu/shader/execution/expression/call/builtin/abs.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/abs.spec.ts index 05d5242f7354..8f89b1157c4c 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/abs.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/abs.spec.ts @@ -28,7 +28,6 @@ import { TypeAbstractFloat, } from '../../../../../util/conversion.js'; import { FP } from '../../../../../util/floating_point.js'; -import { fullF32Range, fullF16Range, fullF64Range } from '../../../../../util/math.js'; import { makeCaseCache } from '../../case_cache.js'; import { allInputSources, onlyConstInputSource, run } from '../../expression.js'; @@ -36,21 +35,20 @@ import { abstractBuiltin, builtin } from './builtin.js'; export const g = makeTestGroup(GPUTest); -export const d = makeCaseCache('abs', { - f32: () => { - return FP.f32.generateScalarToIntervalCases(fullF32Range(), 'unfiltered', FP.f32.absInterval); - }, - f16: () => { - return FP.f16.generateScalarToIntervalCases(fullF16Range(), 'unfiltered', FP.f16.absInterval); - }, - abstract: () => { - return FP.abstract.generateScalarToIntervalCases( - fullF64Range(), - 'unfiltered', - FP.abstract.absInterval - ); - }, -}); +// Cases: [f32|f16|abstract] +const cases = (['f32', 'f16', 'abstract'] as const) + .map(trait => ({ + [`${trait}`]: () => { + return FP[trait].generateScalarToIntervalCases( + FP[trait].scalarRange(), + 'unfiltered', + FP[trait].absInterval + ); + }, + })) + .reduce((a, b) => ({ ...a, ...b }), {}); + +export const d = makeCaseCache('abs', cases); g.test('abstract_int') .specURL('https://www.w3.org/TR/WGSL/#integer-builtin-functions') diff --git a/src/webgpu/shader/execution/expression/call/builtin/acos.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/acos.spec.ts index 5755c0790515..5c865cbd48a4 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/acos.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/acos.spec.ts @@ -11,7 +11,7 @@ import { makeTestGroup } from '../../../../../../common/framework/test_group.js' import { GPUTest } from '../../../../../gpu_test.js'; import { TypeF32, TypeF16 } from '../../../../../util/conversion.js'; import { FP } from '../../../../../util/floating_point.js'; -import { linearRange, fullF32Range, fullF16Range } from '../../../../../util/math.js'; +import { linearRange } from '../../../../../util/math.js'; import { makeCaseCache } from '../../case_cache.js'; import { allInputSources, run } from '../../expression.js'; @@ -19,30 +19,22 @@ import { builtin } from './builtin.js'; export const g = makeTestGroup(GPUTest); -const f32_inputs = [ - ...linearRange(-1, 1, 100), // acos is defined on [-1, 1] - ...fullF32Range(), -]; - -const f16_inputs = [ - ...linearRange(-1, 1, 100), // acos is defined on [-1, 1] - ...fullF16Range(), -]; +// Cases: [f32|f16]_[non_]const +const cases = (['f32', 'f16'] as const) + .flatMap(trait => + ([true, false] as const).map(nonConst => ({ + [`${trait}_${nonConst ? 'non_const' : 'const'}`]: () => { + return FP[trait].generateScalarToIntervalCases( + [...linearRange(-1, 1, 100), ...FP[trait].scalarRange()], // acos is defined on [-1, 1] + nonConst ? 'unfiltered' : 'finite', + FP[trait].acosInterval + ); + }, + })) + ) + .reduce((a, b) => ({ ...a, ...b }), {}); -export const d = makeCaseCache('acos', { - f32_const: () => { - return FP.f32.generateScalarToIntervalCases(f32_inputs, 'finite', FP.f32.acosInterval); - }, - f32_non_const: () => { - return FP.f32.generateScalarToIntervalCases(f32_inputs, 'unfiltered', FP.f32.acosInterval); - }, - f16_const: () => { - return FP.f16.generateScalarToIntervalCases(f16_inputs, 'finite', FP.f16.acosInterval); - }, - f16_non_const: () => { - return FP.f16.generateScalarToIntervalCases(f16_inputs, 'unfiltered', FP.f16.acosInterval); - }, -}); +export const d = makeCaseCache('acos', cases); g.test('abstract_float') .specURL('https://www.w3.org/TR/WGSL/#float-builtin-functions') diff --git a/src/webgpu/shader/execution/expression/call/builtin/acosh.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/acosh.spec.ts index cc78ce3eee4f..e5c5eaa6d590 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/acosh.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/acosh.spec.ts @@ -15,7 +15,7 @@ import { makeTestGroup } from '../../../../../../common/framework/test_group.js' import { GPUTest } from '../../../../../gpu_test.js'; import { TypeF32, TypeF16 } from '../../../../../util/conversion.js'; import { FP } from '../../../../../util/floating_point.js'; -import { biasedRange, fullF32Range, fullF16Range } from '../../../../../util/math.js'; +import { biasedRange } from '../../../../../util/math.js'; import { makeCaseCache } from '../../case_cache.js'; import { allInputSources, run } from '../../expression.js'; @@ -23,29 +23,22 @@ import { builtin } from './builtin.js'; export const g = makeTestGroup(GPUTest); -const f32_inputs = [ - ...biasedRange(1, 2, 100), // x near 1 can be problematic to implement - ...fullF32Range(), -]; -const f16_inputs = [ - ...biasedRange(1, 2, 100), // x near 1 can be problematic to implement - ...fullF16Range(), -]; +// Cases: [f32|f16]_[non_]const +const cases = (['f32', 'f16'] as const) + .flatMap(trait => + ([true, false] as const).map(nonConst => ({ + [`${trait}_${nonConst ? 'non_const' : 'const'}`]: () => { + return FP[trait].generateScalarToIntervalCases( + [...biasedRange(1, 2, 100), ...FP[trait].scalarRange()], // x near 1 can be problematic to implement + nonConst ? 'unfiltered' : 'finite', + ...FP[trait].acoshIntervals + ); + }, + })) + ) + .reduce((a, b) => ({ ...a, ...b }), {}); -export const d = makeCaseCache('acosh', { - f32_const: () => { - return FP.f32.generateScalarToIntervalCases(f32_inputs, 'finite', ...FP.f32.acoshIntervals); - }, - f32_non_const: () => { - return FP.f32.generateScalarToIntervalCases(f32_inputs, 'unfiltered', ...FP.f32.acoshIntervals); - }, - f16_const: () => { - return FP.f16.generateScalarToIntervalCases(f16_inputs, 'finite', ...FP.f16.acoshIntervals); - }, - f16_non_const: () => { - return FP.f16.generateScalarToIntervalCases(f16_inputs, 'unfiltered', ...FP.f16.acoshIntervals); - }, -}); +export const d = makeCaseCache('acosh', cases); g.test('abstract_float') .specURL('https://www.w3.org/TR/WGSL/#float-builtin-functions') diff --git a/src/webgpu/shader/execution/expression/call/builtin/asin.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/asin.spec.ts index 8d18ebb30325..add7f069d1c9 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/asin.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/asin.spec.ts @@ -11,7 +11,7 @@ import { makeTestGroup } from '../../../../../../common/framework/test_group.js' import { GPUTest } from '../../../../../gpu_test.js'; import { TypeF32, TypeF16 } from '../../../../../util/conversion.js'; import { FP } from '../../../../../util/floating_point.js'; -import { linearRange, fullF32Range, fullF16Range } from '../../../../../util/math.js'; +import { linearRange } from '../../../../../util/math.js'; import { makeCaseCache } from '../../case_cache.js'; import { allInputSources, run } from '../../expression.js'; @@ -19,30 +19,22 @@ import { builtin } from './builtin.js'; export const g = makeTestGroup(GPUTest); -const f32_inputs = [ - ...linearRange(-1, 1, 100), // asin is defined on [-1, 1] - ...fullF32Range(), -]; - -const f16_inputs = [ - ...linearRange(-1, 1, 100), // asin is defined on [-1, 1] - ...fullF16Range(), -]; +// Cases: [f32|f16]_[non_]const +const cases = (['f32', 'f16'] as const) + .flatMap(trait => + ([true, false] as const).map(nonConst => ({ + [`${trait}_${nonConst ? 'non_const' : 'const'}`]: () => { + return FP[trait].generateScalarToIntervalCases( + [...linearRange(-1, 1, 100), ...FP[trait].scalarRange()], // asin is defined on [-1, 1] + nonConst ? 'unfiltered' : 'finite', + FP[trait].asinInterval + ); + }, + })) + ) + .reduce((a, b) => ({ ...a, ...b }), {}); -export const d = makeCaseCache('asin', { - f32_const: () => { - return FP.f32.generateScalarToIntervalCases(f32_inputs, 'finite', FP.f32.asinInterval); - }, - f32_non_const: () => { - return FP.f32.generateScalarToIntervalCases(f32_inputs, 'unfiltered', FP.f32.asinInterval); - }, - f16_const: () => { - return FP.f16.generateScalarToIntervalCases(f16_inputs, 'finite', FP.f16.asinInterval); - }, - f16_non_const: () => { - return FP.f16.generateScalarToIntervalCases(f16_inputs, 'unfiltered', FP.f16.asinInterval); - }, -}); +export const d = makeCaseCache('asin', cases); g.test('abstract_float') .specURL('https://www.w3.org/TR/WGSL/#float-builtin-functions') diff --git a/src/webgpu/shader/execution/expression/call/builtin/asinh.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/asinh.spec.ts index 9a8384e09034..b25edd5f9e67 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/asinh.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/asinh.spec.ts @@ -14,7 +14,6 @@ import { makeTestGroup } from '../../../../../../common/framework/test_group.js' import { GPUTest } from '../../../../../gpu_test.js'; import { TypeF32, TypeF16 } from '../../../../../util/conversion.js'; import { FP } from '../../../../../util/floating_point.js'; -import { fullF32Range, fullF16Range } from '../../../../../util/math.js'; import { makeCaseCache } from '../../case_cache.js'; import { allInputSources, run } from '../../expression.js'; @@ -22,14 +21,20 @@ import { builtin } from './builtin.js'; export const g = makeTestGroup(GPUTest); -export const d = makeCaseCache('asinh', { - f32: () => { - return FP.f32.generateScalarToIntervalCases(fullF32Range(), 'unfiltered', FP.f32.asinhInterval); - }, - f16: () => { - return FP.f16.generateScalarToIntervalCases(fullF16Range(), 'unfiltered', FP.f16.asinhInterval); - }, -}); +// Cases: [f32|f16] +const cases = (['f32', 'f16'] as const) + .map(trait => ({ + [`${trait}`]: () => { + return FP[trait].generateScalarToIntervalCases( + FP[trait].scalarRange(), + 'unfiltered', + FP[trait].asinhInterval + ); + }, + })) + .reduce((a, b) => ({ ...a, ...b }), {}); + +export const d = makeCaseCache('asinh', cases); g.test('abstract_float') .specURL('https://www.w3.org/TR/WGSL/#float-builtin-functions') diff --git a/src/webgpu/shader/execution/expression/call/builtin/atan.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/atan.spec.ts index 3d0d3e67252e..2b0a50727640 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/atan.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/atan.spec.ts @@ -12,7 +12,6 @@ import { makeTestGroup } from '../../../../../../common/framework/test_group.js' import { GPUTest } from '../../../../../gpu_test.js'; import { TypeF32, TypeF16 } from '../../../../../util/conversion.js'; import { FP } from '../../../../../util/floating_point.js'; -import { fullF32Range, fullF16Range } from '../../../../../util/math.js'; import { makeCaseCache } from '../../case_cache.js'; import { allInputSources, run } from '../../expression.js'; @@ -22,23 +21,22 @@ export const g = makeTestGroup(GPUTest); const known_values = [-Math.sqrt(3), -1, -1 / Math.sqrt(3), 0, 1, 1 / Math.sqrt(3), Math.sqrt(3)]; -const f32_inputs = [...known_values, ...fullF32Range()]; -const f16_inputs = [...known_values, ...fullF16Range()]; +// Cases: [f32|f16]_[non_]const +const cases = (['f32', 'f16'] as const) + .flatMap(trait => + ([true, false] as const).map(nonConst => ({ + [`${trait}_${nonConst ? 'non_const' : 'const'}`]: () => { + return FP[trait].generateScalarToIntervalCases( + [...known_values, ...FP[trait].scalarRange()], + nonConst ? 'unfiltered' : 'finite', + FP[trait].atanInterval + ); + }, + })) + ) + .reduce((a, b) => ({ ...a, ...b }), {}); -export const d = makeCaseCache('atan', { - f32_const: () => { - return FP.f32.generateScalarToIntervalCases(f32_inputs, 'finite', FP.f32.atanInterval); - }, - f32_non_const: () => { - return FP.f32.generateScalarToIntervalCases(f32_inputs, 'unfiltered', FP.f32.atanInterval); - }, - f16_const: () => { - return FP.f16.generateScalarToIntervalCases(f16_inputs, 'finite', FP.f16.atanInterval); - }, - f16_non_const: () => { - return FP.f16.generateScalarToIntervalCases(f16_inputs, 'unfiltered', FP.f16.atanInterval); - }, -}); +export const d = makeCaseCache('atan', cases); g.test('abstract_float') .specURL('https://www.w3.org/TR/WGSL/#float-builtin-functions') diff --git a/src/webgpu/shader/execution/expression/call/builtin/atan2.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/atan2.spec.ts index fbace73dd204..69eb08791e10 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/atan2.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/atan2.spec.ts @@ -11,7 +11,7 @@ import { makeTestGroup } from '../../../../../../common/framework/test_group.js' import { GPUTest } from '../../../../../gpu_test.js'; import { TypeF32, TypeF16 } from '../../../../../util/conversion.js'; import { FP } from '../../../../../util/floating_point.js'; -import { linearRange, sparseF32Range, sparseF16Range } from '../../../../../util/math.js'; +import { linearRange } from '../../../../../util/math.js'; import { makeCaseCache } from '../../case_cache.js'; import { allInputSources, run } from '../../expression.js'; @@ -19,22 +19,22 @@ import { builtin } from './builtin.js'; export const g = makeTestGroup(GPUTest); +// Cases: [f32|f16]_[non_]const const cases = (['f32', 'f16'] as const) .flatMap(kind => ([true, false] as const).map(nonConst => ({ [`${kind}_${nonConst ? 'non_const' : 'const'}`]: () => { - const fp = FP[kind]; // Using sparse range since there are N^2 cases being generated, and also including extra values // around 0, where there is a discontinuity that implementations may behave badly at. const numeric_range = [ - ...(kind === 'f32' ? sparseF32Range() : sparseF16Range()), - ...linearRange(fp.constants().negative.max, fp.constants().positive.min, 10), + ...FP[kind].sparseScalarRange(), + ...linearRange(FP[kind].constants().negative.max, FP[kind].constants().positive.min, 10), ]; - return fp.generateScalarPairToIntervalCases( + return FP[kind].generateScalarPairToIntervalCases( numeric_range, numeric_range, nonConst ? 'unfiltered' : 'finite', - fp.atan2Interval + FP[kind].atan2Interval ); }, })) diff --git a/src/webgpu/shader/execution/expression/call/builtin/atanh.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/atanh.spec.ts index 90f322a7eaa0..e0b88f9efa96 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/atanh.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/atanh.spec.ts @@ -12,10 +12,9 @@ Note: The result is not mathematically meaningful when abs(e) >= 1. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { kValue } from '../../../../../util/constants.js'; import { TypeF32, TypeF16 } from '../../../../../util/conversion.js'; import { FP } from '../../../../../util/floating_point.js'; -import { biasedRange, fullF32Range, fullF16Range } from '../../../../../util/math.js'; +import { biasedRange } from '../../../../../util/math.js'; import { makeCaseCache } from '../../case_cache.js'; import { allInputSources, run } from '../../expression.js'; @@ -23,35 +22,30 @@ import { builtin } from './builtin.js'; export const g = makeTestGroup(GPUTest); -const f32_inputs = [ - ...biasedRange(kValue.f32.negative.less_than_one, -0.9, 20), // discontinuity at x = -1 - -1, - ...biasedRange(kValue.f32.positive.less_than_one, 0.9, 20), // discontinuity at x = 1 - 1, - ...fullF32Range(), -]; -const f16_inputs = [ - ...biasedRange(kValue.f16.negative.less_than_one, -0.9, 20), // discontinuity at x = -1 - -1, - ...biasedRange(kValue.f16.positive.less_than_one, 0.9, 20), // discontinuity at x = 1 - 1, - ...fullF16Range(), -]; +// Cases: [f32|f16]_[non_]const +const cases = (['f32', 'f16'] as const) + .flatMap(trait => + ([true, false] as const).map(nonConst => ({ + [`${trait}_${nonConst ? 'non_const' : 'const'}`]: () => { + return FP[trait].generateScalarToIntervalCases( + [ + // discontinuity at x = -1 + ...biasedRange(FP[trait].constants().negative.less_than_one, -0.9, 20), + -1, + // discontinuity at x = 1 + ...biasedRange(FP[trait].constants().positive.less_than_one, 0.9, 20), + 1, + ...FP[trait].scalarRange(), + ], + nonConst ? 'unfiltered' : 'finite', + FP[trait].atanhInterval + ); + }, + })) + ) + .reduce((a, b) => ({ ...a, ...b }), {}); -export const d = makeCaseCache('atanh', { - f32_const: () => { - return FP.f32.generateScalarToIntervalCases(f32_inputs, 'finite', FP.f32.atanhInterval); - }, - f32_non_const: () => { - return FP.f32.generateScalarToIntervalCases(f32_inputs, 'unfiltered', FP.f32.atanhInterval); - }, - f16_const: () => { - return FP.f16.generateScalarToIntervalCases(f16_inputs, 'finite', FP.f16.atanhInterval); - }, - f16_non_const: () => { - return FP.f16.generateScalarToIntervalCases(f16_inputs, 'unfiltered', FP.f16.atanhInterval); - }, -}); +export const d = makeCaseCache('atanh', cases); g.test('abstract_float') .specURL('https://www.w3.org/TR/WGSL/#float-builtin-functions') diff --git a/src/webgpu/shader/execution/expression/call/builtin/bitcast.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/bitcast.spec.ts index 390129f2c73a..13663a28409f 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/bitcast.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/bitcast.spec.ts @@ -40,10 +40,10 @@ import { } from '../../../../../util/conversion.js'; import { FPInterval, FP } from '../../../../../util/floating_point.js'; import { - fullF32Range, + scalarF32Range, fullI32Range, fullU32Range, - fullF16Range, + scalarF16Range, linearRange, isSubnormalNumberF32, isSubnormalNumberF16, @@ -92,11 +92,11 @@ const f32ZerosInterval: FPInterval = new FPInterval('f32', -0.0, 0.0); // f32FiniteRange is a list of finite f32s. fullF32Range() already // has +0, we only need to add -0. -const f32FiniteRange: number[] = [...fullF32Range(), kValue.f32.negative.zero]; +const f32FiniteRange: number[] = [...scalarF32Range(), kValue.f32.negative.zero]; const f32RangeWithInfAndNaN: number[] = [...f32FiniteRange, ...f32InfAndNaNInF32]; // F16 values, finite, Inf/NaN, and zeros. Represented in float and u16. -const f16FiniteInF16: number[] = [...fullF16Range(), kValue.f16.negative.zero]; +const f16FiniteInF16: number[] = [...scalarF16Range(), kValue.f16.negative.zero]; const f16FiniteInU16: number[] = f16FiniteInF16.map(u => reinterpretF16AsU16(u)); const f16InfAndNaNInU16: number[] = [ diff --git a/src/webgpu/shader/execution/expression/call/builtin/ceil.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/ceil.spec.ts index 6cdf90986b9f..8b8f9dbbaa6a 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/ceil.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/ceil.spec.ts @@ -12,7 +12,6 @@ import { makeTestGroup } from '../../../../../../common/framework/test_group.js' import { GPUTest } from '../../../../../gpu_test.js'; import { TypeF32, TypeF16 } from '../../../../../util/conversion.js'; import { FP } from '../../../../../util/floating_point.js'; -import { fullF32Range, fullF16Range } from '../../../../../util/math.js'; import { makeCaseCache } from '../../case_cache.js'; import { allInputSources, run } from '../../expression.js'; @@ -20,52 +19,28 @@ import { builtin } from './builtin.js'; export const g = makeTestGroup(GPUTest); -export const d = makeCaseCache('ceil', { - f32: () => { - return FP.f32.generateScalarToIntervalCases( - [ - // Small positive numbers - 0.1, - 0.9, - 1.0, - 1.1, - 1.9, - // Small negative numbers - -0.1, - -0.9, - -1.0, - -1.1, - -1.9, - 0x80000000, // https://github.com/gpuweb/cts/issues/2766 - ...fullF32Range(), - ], - 'unfiltered', - FP.f32.ceilInterval - ); - }, - f16: () => { - return FP.f16.generateScalarToIntervalCases( - [ - // Small positive numbers - 0.1, - 0.9, - 1.0, - 1.1, - 1.9, - // Small negative numbers - -0.1, - -0.9, - -1.0, - -1.1, - -1.9, - 0x8000, // https://github.com/gpuweb/cts/issues/2766 - ...fullF16Range(), - ], - 'unfiltered', - FP.f16.ceilInterval - ); - }, -}); +const kSmallMagnitudeTestValues = [0.1, 0.9, 1.0, 1.1, 1.9, -0.1, -0.9, -1.0, -1.1, -1.9]; + +// See https://github.com/gpuweb/cts/issues/2766 for details +const kIssue2766Value = { + f32: 0x8000_0000, + f16: 0x8000, +}; + +// Cases: [f32|f16] +const cases = (['f32', 'f16'] as const) + .map(trait => ({ + [`${trait}`]: () => { + return FP[trait].generateScalarToIntervalCases( + [...kSmallMagnitudeTestValues, kIssue2766Value[trait], ...FP[trait].scalarRange()], + 'unfiltered', + FP[trait].ceilInterval + ); + }, + })) + .reduce((a, b) => ({ ...a, ...b }), {}); + +export const d = makeCaseCache('ceil', cases); g.test('abstract_float') .specURL('https://www.w3.org/TR/WGSL/#float-builtin-functions') diff --git a/src/webgpu/shader/execution/expression/call/builtin/clamp.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/clamp.spec.ts index 0113fd656f8d..a2f8f52843c6 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/clamp.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/clamp.spec.ts @@ -25,7 +25,6 @@ import { TypeAbstractFloat, } from '../../../../../util/conversion.js'; import { FP } from '../../../../../util/floating_point.js'; -import { sparseF32Range, sparseF16Range, sparseF64Range } from '../../../../../util/math.js'; import { makeCaseCache } from '../../case_cache.js'; import { allInputSources, Case, onlyConstInputSource, run } from '../../expression.js'; @@ -48,41 +47,11 @@ const i32Values = [ kValue.i32.positive.max, ]; -export const d = makeCaseCache('clamp', { - u32_non_const: () => { - return generateIntegerTestCases(u32Values, TypeU32, 'non-const'); - }, - u32_const: () => { - return generateIntegerTestCases(u32Values, TypeU32, 'const'); - }, - i32_non_const: () => { - return generateIntegerTestCases(i32Values, TypeI32, 'non-const'); - }, - i32_const: () => { - return generateIntegerTestCases(i32Values, TypeI32, 'const'); - }, - f32_const: () => { - return generateFloatTestCases(sparseF32Range(), 'f32', 'const'); - }, - f32_non_const: () => { - return generateFloatTestCases(sparseF32Range(), 'f32', 'non-const'); - }, - f16_const: () => { - return generateFloatTestCases(sparseF16Range(), 'f16', 'const'); - }, - f16_non_const: () => { - return generateFloatTestCases(sparseF16Range(), 'f16', 'non-const'); - }, - abstract: () => { - return generateFloatTestCases(sparseF64Range(), 'abstract', 'const'); - }, -}); - /** @returns a set of clamp test cases from an ascending list of integer values */ function generateIntegerTestCases( test_values: Array, type: ScalarType, - stage: 'const' | 'non-const' + stage: 'const' | 'non_const' ): Array { return test_values.flatMap(low => test_values.flatMap(high => @@ -99,7 +68,7 @@ function generateIntegerTestCases( function generateFloatTestCases( test_values: readonly number[], trait: 'f32' | 'f16' | 'abstract', - stage: 'const' | 'non-const' + stage: 'const' | 'non_const' ): Array { return test_values.flatMap(low => test_values.flatMap(high => @@ -119,6 +88,41 @@ function generateFloatTestCases( ); } +// Cases: [f32|f16|abstract]_[non_]const +// abstract_non_const is empty and unused +const fp_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 generateFloatTestCases( + FP[trait].sparseScalarRange(), + trait, + nonConst ? 'non_const' : 'const' + ); + }, + })) + ) + .reduce((a, b) => ({ ...a, ...b }), {}); + +export const d = makeCaseCache('clamp', { + u32_non_const: () => { + return generateIntegerTestCases(u32Values, TypeU32, 'non_const'); + }, + u32_const: () => { + return generateIntegerTestCases(u32Values, TypeU32, 'const'); + }, + i32_non_const: () => { + return generateIntegerTestCases(i32Values, TypeI32, 'non_const'); + }, + i32_const: () => { + return generateIntegerTestCases(i32Values, TypeI32, 'const'); + }, + ...fp_cases, +}); + g.test('abstract_int') .specURL('https://www.w3.org/TR/WGSL/#integer-builtin-functions') .desc(`abstract int tests`) @@ -158,7 +162,7 @@ g.test('abstract_float') .combine('vectorize', [undefined, 2, 3, 4] as const) ) .fn(async t => { - const cases = await d.get('abstract'); + const cases = await d.get('abstract_const'); await run( t, abstractBuiltin('clamp'), diff --git a/src/webgpu/shader/execution/expression/call/builtin/cos.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/cos.spec.ts index 723bca2efd85..bd2eb6089048 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/cos.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/cos.spec.ts @@ -11,7 +11,7 @@ import { makeTestGroup } from '../../../../../../common/framework/test_group.js' import { GPUTest } from '../../../../../gpu_test.js'; import { TypeF32, TypeF16 } from '../../../../../util/conversion.js'; import { FP } from '../../../../../util/floating_point.js'; -import { fullF32Range, fullF16Range, linearRange } from '../../../../../util/math.js'; +import { linearRange } from '../../../../../util/math.js'; import { makeCaseCache } from '../../case_cache.js'; import { allInputSources, run } from '../../expression.js'; @@ -19,30 +19,24 @@ import { builtin } from './builtin.js'; export const g = makeTestGroup(GPUTest); -export const d = makeCaseCache('cos', { - f32: () => { - return FP.f32.generateScalarToIntervalCases( - [ - // Well-defined accuracy range - ...linearRange(-Math.PI, Math.PI, 1000), - ...fullF32Range(), - ], - 'unfiltered', - FP.f32.cosInterval - ); - }, - f16: () => { - return FP.f16.generateScalarToIntervalCases( - [ - // Well-defined accuracy range - ...linearRange(-Math.PI, Math.PI, 1000), - ...fullF16Range(), - ], - 'unfiltered', - FP.f16.cosInterval - ); - }, -}); +// Cases: [f32|f16] +const cases = (['f32', 'f16'] as const) + .map(trait => ({ + [`${trait}`]: () => { + return FP[trait].generateScalarToIntervalCases( + [ + // Well-defined accuracy range + ...linearRange(-Math.PI, Math.PI, 100), + ...FP[trait].scalarRange(), + ], + 'unfiltered', + FP[trait].cosInterval + ); + }, + })) + .reduce((a, b) => ({ ...a, ...b }), {}); + +export const d = makeCaseCache('cos', cases); g.test('abstract_float') .specURL('https://www.w3.org/TR/WGSL/#float-builtin-functions') diff --git a/src/webgpu/shader/execution/expression/call/builtin/cosh.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/cosh.spec.ts index 37fb961c984d..296e3a4b3ef8 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/cosh.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/cosh.spec.ts @@ -11,7 +11,6 @@ import { makeTestGroup } from '../../../../../../common/framework/test_group.js' import { GPUTest } from '../../../../../gpu_test.js'; import { TypeF32, TypeF16 } from '../../../../../util/conversion.js'; import { FP } from '../../../../../util/floating_point.js'; -import { fullF32Range, fullF16Range } from '../../../../../util/math.js'; import { makeCaseCache } from '../../case_cache.js'; import { allInputSources, run } from '../../expression.js'; @@ -19,20 +18,22 @@ import { builtin } from './builtin.js'; export const g = makeTestGroup(GPUTest); -export const d = makeCaseCache('cosh', { - f32_const: () => { - return FP.f32.generateScalarToIntervalCases(fullF32Range(), 'finite', FP.f32.coshInterval); - }, - f32_non_const: () => { - return FP.f32.generateScalarToIntervalCases(fullF32Range(), 'unfiltered', FP.f32.coshInterval); - }, - f16_const: () => { - return FP.f16.generateScalarToIntervalCases(fullF16Range(), 'finite', FP.f16.coshInterval); - }, - f16_non_const: () => { - return FP.f16.generateScalarToIntervalCases(fullF16Range(), 'unfiltered', FP.f16.coshInterval); - }, -}); +// Cases: [f32|f16] +const cases = (['f32', 'f16'] as const) + .flatMap(trait => + ([true, false] as const).map(nonConst => ({ + [`${trait}_${nonConst ? 'non_const' : 'const'}`]: () => { + return FP[trait].generateScalarToIntervalCases( + FP[trait].scalarRange(), + nonConst ? 'unfiltered' : 'finite', + FP[trait].coshInterval + ); + }, + })) + ) + .reduce((a, b) => ({ ...a, ...b }), {}); + +export const d = makeCaseCache('cosh', cases); g.test('abstract_float') .specURL('https://www.w3.org/TR/WGSL/#float-builtin-functions') diff --git a/src/webgpu/shader/execution/expression/call/builtin/degrees.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/degrees.spec.ts index f82153ffcaca..9e00a4a28a95 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/degrees.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/degrees.spec.ts @@ -11,7 +11,6 @@ import { makeTestGroup } from '../../../../../../common/framework/test_group.js' import { GPUTest } from '../../../../../gpu_test.js'; import { TypeAbstractFloat, TypeF16, TypeF32 } from '../../../../../util/conversion.js'; import { FP } from '../../../../../util/floating_point.js'; -import { fullF16Range, fullF32Range, fullF64Range } from '../../../../../util/math.js'; import { makeCaseCache } from '../../case_cache.js'; import { allInputSources, onlyConstInputSource, run } from '../../expression.js'; @@ -19,35 +18,26 @@ import { abstractBuiltin, builtin } from './builtin.js'; export const g = makeTestGroup(GPUTest); -export const d = makeCaseCache('degrees', { - f32_const: () => { - return FP.f32.generateScalarToIntervalCases(fullF32Range(), 'finite', FP.f32.degreesInterval); - }, - f32_non_const: () => { - return FP.f32.generateScalarToIntervalCases( - fullF32Range(), - 'unfiltered', - FP.f32.degreesInterval - ); - }, - f16_const: () => { - return FP.f16.generateScalarToIntervalCases(fullF16Range(), 'finite', FP.f16.degreesInterval); - }, - f16_non_const: () => { - return FP.f16.generateScalarToIntervalCases( - fullF16Range(), - 'unfiltered', - FP.f16.degreesInterval - ); - }, - abstract: () => { - return FP.abstract.generateScalarToIntervalCases( - fullF64Range(), - 'finite', - FP.abstract.degreesInterval - ); - }, -}); +// Cases: [f32|f16|abstract]_[non_]const +// abstract_non_const is empty and not used +const 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].generateScalarToIntervalCases( + FP[trait].scalarRange(), + nonConst ? 'unfiltered' : 'finite', + FP[trait].degreesInterval + ); + }, + })) + ) + .reduce((a, b) => ({ ...a, ...b }), {}); + +export const d = makeCaseCache('degrees', cases); g.test('abstract_float') .specURL('https://www.w3.org/TR/WGSL/#float-builtin-functions') diff --git a/src/webgpu/shader/execution/expression/call/builtin/distance.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/distance.spec.ts index e4804d92d4bc..69b9606bf0bc 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/distance.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/distance.spec.ts @@ -12,7 +12,6 @@ import { makeTestGroup } from '../../../../../../common/framework/test_group.js' import { GPUTest } from '../../../../../gpu_test.js'; import { TypeF32, TypeF16, TypeVec } from '../../../../../util/conversion.js'; import { FP } from '../../../../../util/floating_point.js'; -import { fullF32Range, fullF16Range } from '../../../../../util/math.js'; import { makeCaseCache } from '../../case_cache.js'; import { allInputSources, run } from '../../expression.js'; @@ -20,6 +19,22 @@ import { builtin } from './builtin.js'; export const g = makeTestGroup(GPUTest); +// Cases: [f32|f16]_[non_]const +const scalar_cases = (['f32', 'f16'] as const) + .flatMap(trait => + ([true, false] as const).map(nonConst => ({ + [`${trait}_${nonConst ? 'non_const' : 'const'}`]: () => { + return FP[trait].generateScalarPairToIntervalCases( + FP[trait].scalarRange(), + FP[trait].scalarRange(), + nonConst ? 'unfiltered' : 'finite', + FP[trait].distanceInterval + ); + }, + })) + ) + .reduce((a, b) => ({ ...a, ...b }), {}); + // Cases: [f32|f16]_vecN_[non_]const const vec_cases = (['f32', 'f16'] as const) .flatMap(trait => @@ -39,38 +54,7 @@ const vec_cases = (['f32', 'f16'] as const) .reduce((a, b) => ({ ...a, ...b }), {}); export const d = makeCaseCache('distance', { - f32_const: () => { - return FP.f32.generateScalarPairToIntervalCases( - fullF32Range(), - fullF32Range(), - 'finite', - FP.f32.distanceInterval - ); - }, - f32_non_const: () => { - return FP.f32.generateScalarPairToIntervalCases( - fullF32Range(), - fullF32Range(), - 'unfiltered', - FP.f32.distanceInterval - ); - }, - f16_const: () => { - return FP.f16.generateScalarPairToIntervalCases( - fullF16Range(), - fullF16Range(), - 'finite', - FP.f16.distanceInterval - ); - }, - f16_non_const: () => { - return FP.f16.generateScalarPairToIntervalCases( - fullF16Range(), - fullF16Range(), - 'unfiltered', - FP.f16.distanceInterval - ); - }, + ...scalar_cases, ...vec_cases, }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/floor.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/floor.spec.ts index 873a6772c360..d756042a9e86 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/floor.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/floor.spec.ts @@ -11,7 +11,6 @@ import { makeTestGroup } from '../../../../../../common/framework/test_group.js' import { GPUTest } from '../../../../../gpu_test.js'; import { TypeF32, TypeF16, TypeAbstractFloat } from '../../../../../util/conversion.js'; import { FP } from '../../../../../util/floating_point.js'; -import { fullF32Range, fullF16Range, fullF64Range } from '../../../../../util/math.js'; import { makeCaseCache } from '../../case_cache.js'; import { allInputSources, onlyConstInputSource, run } from '../../expression.js'; @@ -21,41 +20,27 @@ export const g = makeTestGroup(GPUTest); const kSmallMagnitudeTestValues = [0.1, 0.9, 1.0, 1.1, 1.9, -0.1, -0.9, -1.0, -1.1, -1.9]; -export const d = makeCaseCache('floor', { - f32: () => { - return FP.f32.generateScalarToIntervalCases( - [ - ...kSmallMagnitudeTestValues, - ...fullF32Range(), - 0x8000_0000, // https://github.com/gpuweb/cts/issues/2766 - ], - 'unfiltered', - FP.f32.floorInterval - ); - }, - f16: () => { - return FP.f16.generateScalarToIntervalCases( - [ - ...kSmallMagnitudeTestValues, - ...fullF16Range(), - 0x8000, // https://github.com/gpuweb/cts/issues/2766 - ], - 'unfiltered', - FP.f16.floorInterval - ); - }, - abstract: () => { - return FP.abstract.generateScalarToIntervalCases( - [ - ...kSmallMagnitudeTestValues, - ...fullF64Range(), - 0x8000_0000_0000_0000, // https://github.com/gpuweb/cts/issues/2766 - ], - 'unfiltered', - FP.abstract.floorInterval - ); - }, -}); +// See https://github.com/gpuweb/cts/issues/2766 for details +const kIssue2766Value = { + abstract: 0x8000_0000_0000_0000, + f32: 0x8000_0000, + f16: 0x8000, +}; + +// Cases: [f32|f16|abstract] +const cases = (['f32', 'f16', 'abstract'] as const) + .map(trait => ({ + [`${trait}`]: () => { + return FP[trait].generateScalarToIntervalCases( + [...kSmallMagnitudeTestValues, kIssue2766Value[trait], ...FP[trait].scalarRange()], + 'unfiltered', + FP[trait].floorInterval + ); + }, + })) + .reduce((a, b) => ({ ...a, ...b }), {}); + +export const d = makeCaseCache('floor', cases); g.test('abstract_float') .specURL('https://www.w3.org/TR/WGSL/#float-builtin-functions') diff --git a/src/webgpu/shader/execution/expression/call/builtin/fma.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/fma.spec.ts index 701f9d7ca970..6a275afad6f5 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/fma.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/fma.spec.ts @@ -11,7 +11,6 @@ import { makeTestGroup } from '../../../../../../common/framework/test_group.js' import { GPUTest } from '../../../../../gpu_test.js'; import { TypeF32, TypeF16, TypeAbstractFloat } from '../../../../../util/conversion.js'; import { FP } from '../../../../../util/floating_point.js'; -import { sparseF32Range, sparseF16Range, sparseF64Range } from '../../../../../util/math.js'; import { makeCaseCache } from '../../case_cache.js'; import { allInputSources, onlyConstInputSource, run } from '../../expression.js'; @@ -19,53 +18,28 @@ import { abstractBuiltin, builtin } from './builtin.js'; export const g = makeTestGroup(GPUTest); -export const d = makeCaseCache('fma', { - f32_const: () => { - return FP.f32.generateScalarTripleToIntervalCases( - sparseF32Range(), - sparseF32Range(), - sparseF32Range(), - 'finite', - FP.f32.fmaInterval - ); - }, - f32_non_const: () => { - return FP.f32.generateScalarTripleToIntervalCases( - sparseF32Range(), - sparseF32Range(), - sparseF32Range(), - 'unfiltered', - FP.f32.fmaInterval - ); - }, - f16_const: () => { - return FP.f16.generateScalarTripleToIntervalCases( - sparseF16Range(), - sparseF16Range(), - sparseF16Range(), - 'finite', - FP.f16.fmaInterval - ); - }, - f16_non_const: () => { - return FP.f16.generateScalarTripleToIntervalCases( - sparseF16Range(), - sparseF16Range(), - sparseF16Range(), - 'unfiltered', - FP.f16.fmaInterval - ); - }, - abstract: () => { - return FP.abstract.generateScalarTripleToIntervalCases( - sparseF64Range(), - sparseF64Range(), - sparseF64Range(), - 'finite', - FP.abstract.fmaInterval - ); - }, -}); +// Cases: [f32|f16|abstract]_[non_]const +// abstract_non_const is empty and not used +const 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(), + FP[trait].sparseScalarRange(), + nonConst ? 'unfiltered' : 'finite', + FP[trait].fmaInterval + ); + }, + })) + ) + .reduce((a, b) => ({ ...a, ...b }), {}); + +export const d = makeCaseCache('fma', cases); g.test('abstract_float') .specURL('https://www.w3.org/TR/WGSL/#float-builtin-functions') @@ -76,7 +50,7 @@ g.test('abstract_float') .combine('vectorize', [undefined, 2, 3, 4] as const) ) .fn(async t => { - const cases = await d.get('abstract'); + const cases = await d.get('abstract_const'); await run( t, abstractBuiltin('fma'), diff --git a/src/webgpu/shader/execution/expression/call/builtin/fract.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/fract.spec.ts index 44ea31fde29f..9f412129733a 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/fract.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/fract.spec.ts @@ -12,7 +12,6 @@ import { makeTestGroup } from '../../../../../../common/framework/test_group.js' import { GPUTest } from '../../../../../gpu_test.js'; import { TypeF32, TypeF16 } from '../../../../../util/conversion.js'; import { FP } from '../../../../../util/floating_point.js'; -import { fullF32Range, fullF16Range } from '../../../../../util/math.js'; import { makeCaseCache } from '../../case_cache.js'; import { allInputSources, run } from '../../expression.js'; @@ -20,54 +19,48 @@ import { builtin } from './builtin.js'; export const g = makeTestGroup(GPUTest); -export const d = makeCaseCache('fract', { - f32: () => { - return FP.f32.generateScalarToIntervalCases( - [ - 0.5, // 0.5 -> 0.5 - 0.9, // ~0.9 -> ~0.9 - 1, // 1 -> 0 - 2, // 2 -> 0 - 1.11, // ~1.11 -> ~0.11 - 10.0001, // ~10.0001 -> ~0.0001 - -0.1, // ~-0.1 -> ~0.9 - -0.5, // -0.5 -> 0.5 - -0.9, // ~-0.9 -> ~0.1 - -1, // -1 -> 0 - -2, // -2 -> 0 - -1.11, // ~-1.11 -> ~0.89 - -10.0001, // -10.0001 -> ~0.9999 - 0x80000000, // https://github.com/gpuweb/cts/issues/2766 - ...fullF32Range(), - ], - 'unfiltered', - FP.f32.fractInterval - ); - }, - f16: () => { - return FP.f16.generateScalarToIntervalCases( - [ - 0.5, // 0.5 -> 0.5 - 0.9, // ~0.9 -> ~0.9 - 1, // 1 -> 0 - 2, // 2 -> 0 - 1.11, // ~1.11 -> ~0.11 - 10.0078125, // 10.0078125 -> 0.0078125 - -0.1, // ~-0.1 -> ~0.9 - -0.5, // -0.5 -> 0.5 - -0.9, // ~-0.9 -> ~0.1 - -1, // -1 -> 0 - -2, // -2 -> 0 - -1.11, // ~-1.11 -> ~0.89 - -10.0078125, // -10.0078125 -> 0.9921875 - 658.5, // 658.5 -> 0.5 - ...fullF16Range(), - ], - 'unfiltered', - FP.f16.fractInterval - ); - }, -}); +const kCommonValues = [ + 0.5, // 0.5 -> 0.5 + 0.9, // ~0.9 -> ~0.9 + 1, // 1 -> 0 + 2, // 2 -> 0 + 1.11, // ~1.11 -> ~0.11 + -0.1, // ~-0.1 -> ~0.9 + -0.5, // -0.5 -> 0.5 + -0.9, // ~-0.9 -> ~0.1 + -1, // -1 -> 0 + -2, // -2 -> 0 + -1.11, // ~-1.11 -> ~0.89 +]; + +const kTraitSpecificValues = { + f32: [ + 10.0001, // ~10.0001 -> ~0.0001 + -10.0001, // -10.0001 -> ~0.9999 + 0x8000_0000, // https://github.com/gpuweb/cts/issues/2766 + ], + f16: [ + 10.0078125, // 10.0078125 -> 0.0078125 + -10.0078125, // -10.0078125 -> 0.9921875 + 658.5, // 658.5 -> 0.5 + 0x8000, // https://github.com/gpuweb/cts/issues/2766 + ], +}; + +// Cases: [f32|f16] +const cases = (['f32', 'f16'] as const) + .map(trait => ({ + [`${trait}`]: () => { + return FP[trait].generateScalarToIntervalCases( + [...kCommonValues, ...kTraitSpecificValues[trait], ...FP[trait].scalarRange()], + 'unfiltered', + FP[trait].fractInterval + ); + }, + })) + .reduce((a, b) => ({ ...a, ...b }), {}); + +export const d = makeCaseCache('fract', cases); g.test('abstract_float') .specURL('https://www.w3.org/TR/WGSL/#float-builtin-functions') diff --git a/src/webgpu/shader/execution/expression/call/builtin/frexp.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/frexp.spec.ts index 9f8829b2b4ae..32565ef23667 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/frexp.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/frexp.spec.ts @@ -27,7 +27,7 @@ import { Vector, } from '../../../../../util/conversion.js'; import { FP } from '../../../../../util/floating_point.js'; -import { frexp, fullF16Range, fullF32Range } from '../../../../../util/math.js'; +import { frexp } from '../../../../../util/math.js'; import { makeCaseCache } from '../../case_cache.js'; import { allInputSources, @@ -50,7 +50,7 @@ function expBuilder(): ShaderBuilder { } /* @returns a fract Case for a given scalar or vector input */ -function makeVectorCaseFract(v: number | readonly number[], trait: 'f32' | 'f16'): Case { +function makeCaseFract(v: number | readonly number[], trait: 'f32' | 'f16'): Case { const fp = FP[trait]; let toInput: (n: readonly number[]) => Scalar | Vector; let toOutput: (n: readonly number[]) => Scalar | Vector; @@ -78,7 +78,7 @@ function makeVectorCaseFract(v: number | readonly number[], trait: 'f32' | 'f16' } /* @returns an exp Case for a given scalar or vector input */ -function makeVectorCaseExp(v: number | readonly number[], trait: 'f32' | 'f16'): Case { +function makeCaseExp(v: number | readonly number[], trait: 'f32' | 'f16'): Case { const fp = FP[trait]; let toInput: (n: readonly number[]) => Scalar | Vector; let toOutput: (n: readonly number[]) => Scalar | Vector; @@ -104,6 +104,7 @@ function makeVectorCaseExp(v: number | readonly number[], trait: 'f32' | 'f16'): return { input: toInput(v), expected: toOutput(fs) }; } + // Cases: [f32|f16]_vecN_[exp|whole] const vec_cases = (['f32', 'f16'] as const) .flatMap(trait => @@ -112,28 +113,28 @@ const vec_cases = (['f32', 'f16'] as const) [`${trait}_vec${dim}_${portion}`]: () => { return FP[trait] .vectorRange(dim) - .map(v => - portion === 'exp' ? makeVectorCaseExp(v, trait) : makeVectorCaseFract(v, trait) - ); + .map(v => (portion === 'exp' ? makeCaseExp(v, trait) : makeCaseFract(v, trait))); }, })) ) ) .reduce((a, b) => ({ ...a, ...b }), {}); +// Cases: [f32|f16]_[exp|whole] +const scalar_cases = (['f32', 'f16'] as const) + .flatMap(trait => + (['exp', 'fract'] as const).map(portion => ({ + [`${trait}_${portion}`]: () => { + return FP[trait] + .scalarRange() + .map(v => (portion === 'exp' ? makeCaseExp(v, trait) : makeCaseFract(v, trait))); + }, + })) + ) + .reduce((a, b) => ({ ...a, ...b }), {}); + export const d = makeCaseCache('frexp', { - f32_fract: () => { - return fullF32Range().map(v => makeVectorCaseFract(v, 'f32')); - }, - f32_exp: () => { - return fullF32Range().map(v => makeVectorCaseExp(v, 'f32')); - }, - f16_fract: () => { - return fullF16Range().map(v => makeVectorCaseFract(v, 'f16')); - }, - f16_exp: () => { - return fullF16Range().map(v => makeVectorCaseExp(v, 'f16')); - }, + ...scalar_cases, ...vec_cases, }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/ldexp.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/ldexp.spec.ts index 382986775203..2eec0c8ead5d 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/ldexp.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/ldexp.spec.ts @@ -18,13 +18,7 @@ import { GPUTest } from '../../../../../gpu_test.js'; import { anyOf } from '../../../../../util/compare.js'; import { i32, TypeF32, TypeF16, TypeI32 } from '../../../../../util/conversion.js'; import { FP } from '../../../../../util/floating_point.js'; -import { - biasedRange, - quantizeToI32, - sparseF32Range, - sparseI32Range, - sparseF16Range, -} from '../../../../../util/math.js'; +import { biasedRange, quantizeToI32, sparseI32Range } from '../../../../../util/math.js'; import { makeCaseCache } from '../../case_cache.js'; import { allInputSources, Case, run } from '../../expression.js'; @@ -61,28 +55,30 @@ const makeCase = (trait: 'f32' | 'f16', e1: number, e2: number): Case => { return { input: [FPTrait.scalarBuilder(e1), i32(e2)], expected }; }; -export const d = makeCaseCache('ldexp', { - f32_non_const: () => { - return sparseF32Range().flatMap(e1 => sparseI32Range().map(e2 => makeCase('f32', e1, e2))); - }, - f32_const: () => { - return sparseF32Range().flatMap(e1 => - biasedRange(-bias.f32 - 10, bias.f32 + 1, 10).flatMap(e2 => - FP.f32.isFinite(e1 * 2 ** quantizeToI32(e2)) ? makeCase('f32', e1, e2) : [] - ) - ); - }, - f16_non_const: () => { - return sparseF16Range().flatMap(e1 => sparseI32Range().map(e2 => makeCase('f16', e1, e2))); - }, - f16_const: () => { - return sparseF16Range().flatMap(e1 => - biasedRange(-bias.f16 - 10, bias.f16 + 1, 10).flatMap(e2 => - FP.f16.isFinite(e1 * 2 ** quantizeToI32(e2)) ? makeCase('f16', e1, e2) : [] - ) - ); - }, -}); +// Cases: [f32|f16]_[non_]const +const cases = (['f32', 'f16'] as const) + .flatMap(trait => + ([true, false] as const).map(nonConst => ({ + [`${trait}_${nonConst ? 'non_const' : 'const'}`]: () => { + if (nonConst) { + return FP[trait] + .sparseScalarRange() + .flatMap(e1 => sparseI32Range().map(e2 => makeCase(trait, e1, e2))); + } + // const + return FP[trait] + .sparseScalarRange() + .flatMap(e1 => + biasedRange(-bias[trait] - 10, bias[trait] + 1, 10).flatMap(e2 => + FP[trait].isFinite(e1 * 2 ** quantizeToI32(e2)) ? makeCase(trait, e1, e2) : [] + ) + ); + }, + })) + ) + .reduce((a, b) => ({ ...a, ...b }), {}); + +export const d = makeCaseCache('ldexp', cases); g.test('abstract_float') .specURL('https://www.w3.org/TR/WGSL/#float-builtin-functions') diff --git a/src/webgpu/shader/execution/expression/call/builtin/length.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/length.spec.ts index c5902b8bdc86..82028dfdf98f 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/length.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/length.spec.ts @@ -11,7 +11,6 @@ import { makeTestGroup } from '../../../../../../common/framework/test_group.js' import { GPUTest } from '../../../../../gpu_test.js'; import { TypeF32, TypeF16, TypeVec } from '../../../../../util/conversion.js'; import { FP } from '../../../../../util/floating_point.js'; -import { fullF32Range, fullF16Range } from '../../../../../util/math.js'; import { makeCaseCache } from '../../case_cache.js'; import { allInputSources, run } from '../../expression.js'; @@ -19,6 +18,19 @@ import { builtin } from './builtin.js'; export const g = makeTestGroup(GPUTest); +// Cases: [f32|f16]_[non_]const +const scalar_cases = (['f32', 'f16'] as const) + .map(trait => ({ + [`${trait}`]: () => { + return FP[trait].generateScalarToIntervalCases( + FP[trait].scalarRange(), + 'unfiltered', + FP[trait].lengthInterval + ); + }, + })) + .reduce((a, b) => ({ ...a, ...b }), {}); + // Cases: [f32|f16]_vecN_[non_]const const vec_cases = (['f32', 'f16'] as const) .flatMap(trait => @@ -37,20 +49,7 @@ const vec_cases = (['f32', 'f16'] as const) .reduce((a, b) => ({ ...a, ...b }), {}); export const d = makeCaseCache('length', { - f32: () => { - return FP.f32.generateScalarToIntervalCases( - fullF32Range(), - 'unfiltered', - FP.f32.lengthInterval - ); - }, - f16: () => { - return FP.f16.generateScalarToIntervalCases( - fullF16Range(), - 'unfiltered', - FP.f16.lengthInterval - ); - }, + ...scalar_cases, ...vec_cases, }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/log.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/log.spec.ts index ac60e2b1bc7f..19e367611f49 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/log.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/log.spec.ts @@ -9,10 +9,9 @@ Returns the natural logarithm of e. Component-wise when T is a vector. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { kValue } from '../../../../../util/constants.js'; import { TypeF32, TypeF16 } from '../../../../../util/conversion.js'; import { FP } from '../../../../../util/floating_point.js'; -import { biasedRange, fullF32Range, fullF16Range, linearRange } from '../../../../../util/math.js'; +import { biasedRange, linearRange } from '../../../../../util/math.js'; import { makeCaseCache } from '../../case_cache.js'; import { allInputSources, run } from '../../expression.js'; @@ -21,33 +20,27 @@ import { builtin } from './builtin.js'; export const g = makeTestGroup(GPUTest); // log's accuracy is defined in three regions { [0, 0.5), [0.5, 2.0], (2.0, +∞] } -const f32_inputs = [ - ...linearRange(kValue.f32.positive.min, 0.5, 20), - ...linearRange(0.5, 2.0, 20), - ...biasedRange(2.0, 2 ** 32, 1000), - ...fullF32Range(), -]; -const f16_inputs = [ - ...linearRange(kValue.f16.positive.min, 0.5, 20), - ...linearRange(0.5, 2.0, 20), - ...biasedRange(2.0, 2 ** 32, 1000), - ...fullF16Range(), -]; +// Cases: [f32|f16]_[non_]const +const cases = (['f32', 'f16'] as const) + .flatMap(trait => + ([true, false] as const).map(nonConst => ({ + [`${trait}_${nonConst ? 'non_const' : 'const'}`]: () => { + return FP[trait].generateScalarToIntervalCases( + [ + ...linearRange(FP[trait].constants().positive.min, 0.5, 20), + ...linearRange(0.5, 2.0, 20), + ...biasedRange(2.0, 2 ** 32, 1000), + ...FP[trait].scalarRange(), + ], + nonConst ? 'unfiltered' : 'finite', + FP[trait].logInterval + ); + }, + })) + ) + .reduce((a, b) => ({ ...a, ...b }), {}); -export const d = makeCaseCache('log', { - f32_const: () => { - return FP.f32.generateScalarToIntervalCases(f32_inputs, 'finite', FP.f32.logInterval); - }, - f32_non_const: () => { - return FP.f32.generateScalarToIntervalCases(f32_inputs, 'unfiltered', FP.f32.logInterval); - }, - f16_const: () => { - return FP.f16.generateScalarToIntervalCases(f16_inputs, 'finite', FP.f16.logInterval); - }, - f16_non_const: () => { - return FP.f16.generateScalarToIntervalCases(f16_inputs, 'unfiltered', FP.f16.logInterval); - }, -}); +export const d = makeCaseCache('log', cases); g.test('abstract_float') .specURL('https://www.w3.org/TR/WGSL/#float-builtin-functions') diff --git a/src/webgpu/shader/execution/expression/call/builtin/log2.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/log2.spec.ts index 37931579b99c..2850a6410033 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/log2.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/log2.spec.ts @@ -9,10 +9,9 @@ Returns the base-2 logarithm of e. Component-wise when T is a vector. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { kValue } from '../../../../../util/constants.js'; import { TypeF32, TypeF16 } from '../../../../../util/conversion.js'; import { FP } from '../../../../../util/floating_point.js'; -import { biasedRange, fullF32Range, fullF16Range, linearRange } from '../../../../../util/math.js'; +import { biasedRange, linearRange } from '../../../../../util/math.js'; import { makeCaseCache } from '../../case_cache.js'; import { allInputSources, run } from '../../expression.js'; @@ -21,33 +20,27 @@ import { builtin } from './builtin.js'; export const g = makeTestGroup(GPUTest); // log2's accuracy is defined in three regions { [0, 0.5), [0.5, 2.0], (2.0, +∞] } -const f32_inputs = [ - ...linearRange(kValue.f32.positive.min, 0.5, 20), - ...linearRange(0.5, 2.0, 20), - ...biasedRange(2.0, 2 ** 32, 1000), - ...fullF32Range(), -]; -const f16_inputs = [ - ...linearRange(kValue.f16.positive.min, 0.5, 20), - ...linearRange(0.5, 2.0, 20), - ...biasedRange(2.0, 2 ** 32, 1000), - ...fullF16Range(), -]; +// Cases: [f32|f16]_[non_]const +const cases = (['f32', 'f16'] as const) + .flatMap(trait => + ([true, false] as const).map(nonConst => ({ + [`${trait}_${nonConst ? 'non_const' : 'const'}`]: () => { + return FP[trait].generateScalarToIntervalCases( + [ + ...linearRange(FP[trait].constants().positive.min, 0.5, 20), + ...linearRange(0.5, 2.0, 20), + ...biasedRange(2.0, 2 ** 32, 1000), + ...FP[trait].scalarRange(), + ], + nonConst ? 'unfiltered' : 'finite', + FP[trait].log2Interval + ); + }, + })) + ) + .reduce((a, b) => ({ ...a, ...b }), {}); -export const d = makeCaseCache('log2', { - f32_const: () => { - return FP.f32.generateScalarToIntervalCases(f32_inputs, 'finite', FP.f32.log2Interval); - }, - f32_non_const: () => { - return FP.f32.generateScalarToIntervalCases(f32_inputs, 'unfiltered', FP.f32.log2Interval); - }, - f16_const: () => { - return FP.f16.generateScalarToIntervalCases(f16_inputs, 'finite', FP.f16.log2Interval); - }, - f16_non_const: () => { - return FP.f16.generateScalarToIntervalCases(f16_inputs, 'unfiltered', FP.f16.log2Interval); - }, -}); +export const d = makeCaseCache('log2', cases); g.test('abstract_float') .specURL('https://www.w3.org/TR/WGSL/#float-builtin-functions') diff --git a/src/webgpu/shader/execution/expression/call/builtin/max.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/max.spec.ts index 6654b4951ce7..7a7d199f4eb8 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/max.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/max.spec.ts @@ -28,7 +28,6 @@ import { TypeAbstractFloat, } from '../../../../../util/conversion.js'; import { FP } from '../../../../../util/floating_point.js'; -import { fullF32Range, fullF16Range, sparseF64Range } from '../../../../../util/math.js'; import { makeCaseCache } from '../../case_cache.js'; import { allInputSources, Case, onlyConstInputSource, run } from '../../expression.js'; @@ -50,32 +49,21 @@ function generateTestCases( export const g = makeTestGroup(GPUTest); -export const d = makeCaseCache('max', { - f32: () => { - return FP.f32.generateScalarPairToIntervalCases( - fullF32Range(), - fullF32Range(), - 'unfiltered', - FP.f32.maxInterval - ); - }, - f16: () => { - return FP.f16.generateScalarPairToIntervalCases( - fullF16Range(), - fullF16Range(), - 'unfiltered', - FP.f16.maxInterval - ); - }, - abstract: () => { - return FP.abstract.generateScalarPairToIntervalCases( - sparseF64Range(), - sparseF64Range(), - 'unfiltered', - FP.abstract.maxInterval - ); - }, -}); +// Cases: [f32|f16|abstract] +const cases = (['f32', 'f16', 'abstract'] as const) + .map(trait => ({ + [`${trait}`]: () => { + return FP[trait].generateScalarPairToIntervalCases( + FP[trait].scalarRange(), + FP[trait].scalarRange(), + 'unfiltered', + FP[trait].maxInterval + ); + }, + })) + .reduce((a, b) => ({ ...a, ...b }), {}); + +export const d = makeCaseCache('max', cases); g.test('abstract_int') .specURL('https://www.w3.org/TR/WGSL/#integer-builtin-functions') diff --git a/src/webgpu/shader/execution/expression/call/builtin/min.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/min.spec.ts index 6c05319546dc..68fb5be8d2d6 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/min.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/min.spec.ts @@ -27,7 +27,6 @@ import { TypeAbstractFloat, } from '../../../../../util/conversion.js'; import { FP } from '../../../../../util/floating_point.js'; -import { fullF32Range, fullF16Range, sparseF64Range } from '../../../../../util/math.js'; import { makeCaseCache } from '../../case_cache.js'; import { allInputSources, Case, onlyConstInputSource, run } from '../../expression.js'; @@ -35,33 +34,6 @@ import { abstractBuiltin, builtin } from './builtin.js'; export const g = makeTestGroup(GPUTest); -export const d = makeCaseCache('min', { - f32: () => { - return FP.f32.generateScalarPairToIntervalCases( - fullF32Range(), - fullF32Range(), - 'unfiltered', - FP.f32.minInterval - ); - }, - f16: () => { - return FP.f16.generateScalarPairToIntervalCases( - fullF16Range(), - fullF16Range(), - 'unfiltered', - FP.f16.minInterval - ); - }, - abstract: () => { - return FP.abstract.generateScalarPairToIntervalCases( - sparseF64Range(), - sparseF64Range(), - 'unfiltered', - FP.abstract.minInterval - ); - }, -}); - /** Generate set of min test cases from list of interesting values */ function generateTestCases( values: Array, @@ -76,6 +48,22 @@ function generateTestCases( return cases; } +// Cases: [f32|f16|abstract] +const cases = (['f32', 'f16', 'abstract'] as const) + .map(trait => ({ + [`${trait}`]: () => { + return FP[trait].generateScalarPairToIntervalCases( + FP[trait].scalarRange(), + FP[trait].scalarRange(), + 'unfiltered', + FP[trait].minInterval + ); + }, + })) + .reduce((a, b) => ({ ...a, ...b }), {}); + +export const d = makeCaseCache('min', cases); + g.test('abstract_int') .specURL('https://www.w3.org/TR/WGSL/#integer-builtin-functions') .desc(`abstract int tests`) 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 7c074712cf03..80b28508ecef 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/mix.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/mix.spec.ts @@ -18,7 +18,6 @@ import { makeTestGroup } from '../../../../../../common/framework/test_group.js' import { GPUTest } from '../../../../../gpu_test.js'; import { TypeVec, TypeF32, TypeF16 } from '../../../../../util/conversion.js'; import { FP } from '../../../../../util/floating_point.js'; -import { sparseF32Range, sparseF16Range } from '../../../../../util/math.js'; import { makeCaseCache } from '../../case_cache.js'; import { allInputSources, run } from '../../expression.js'; @@ -26,6 +25,23 @@ import { builtin } from './builtin.js'; export const g = makeTestGroup(GPUTest); +// Cases: [f32|f16]_[non_]const +const scalar_cases = (['f32', 'f16'] as const) + .flatMap(trait => + ([true, false] as const).map(nonConst => ({ + [`${trait}_${nonConst ? 'non_const' : 'const'}`]: () => { + return FP[trait].generateScalarTripleToIntervalCases( + FP[trait].sparseScalarRange(), + FP[trait].sparseScalarRange(), + FP[trait].sparseScalarRange(), + nonConst ? 'unfiltered' : 'finite', + ...FP[trait].mixIntervals + ); + }, + })) + ) + .reduce((a, b) => ({ ...a, ...b }), {}); + // Cases: [f32|f16]_vecN_scalar_[non_]const const vec_scalar_cases = (['f32', 'f16'] as const) .flatMap(trait => @@ -35,8 +51,7 @@ const vec_scalar_cases = (['f32', 'f16'] as const) return FP[trait].generateVectorPairScalarToVectorComponentWiseCase( FP[trait].sparseVectorRange(dim), FP[trait].sparseVectorRange(dim), - // NB: Refactor this when adding scalar ranges to FPTrait API - trait === 'f32' ? sparseF32Range() : sparseF16Range(), + FP[trait].sparseScalarRange(), nonConst ? 'unfiltered' : 'finite', ...FP[trait].mixIntervals ); @@ -47,42 +62,7 @@ const vec_scalar_cases = (['f32', 'f16'] as const) .reduce((a, b) => ({ ...a, ...b }), {}); export const d = makeCaseCache('mix', { - f32_const: () => { - return FP.f32.generateScalarTripleToIntervalCases( - sparseF32Range(), - sparseF32Range(), - sparseF32Range(), - 'finite', - ...FP.f32.mixIntervals - ); - }, - f32_non_const: () => { - return FP.f32.generateScalarTripleToIntervalCases( - sparseF32Range(), - sparseF32Range(), - sparseF32Range(), - 'unfiltered', - ...FP.f32.mixIntervals - ); - }, - f16_const: () => { - return FP.f16.generateScalarTripleToIntervalCases( - sparseF16Range(), - sparseF16Range(), - sparseF16Range(), - 'finite', - ...FP.f16.mixIntervals - ); - }, - f16_non_const: () => { - return FP.f16.generateScalarTripleToIntervalCases( - sparseF16Range(), - sparseF16Range(), - sparseF16Range(), - 'unfiltered', - ...FP.f16.mixIntervals - ); - }, + ...scalar_cases, ...vec_scalar_cases, }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/modf.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/modf.spec.ts index 22cdfb93aa99..d6b82957b202 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/modf.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/modf.spec.ts @@ -26,7 +26,6 @@ import { TypeVec, } from '../../../../../util/conversion.js'; import { FP, FPKind } from '../../../../../util/floating_point.js'; -import { fullF16Range, fullF32Range, fullF64Range } from '../../../../../util/math.js'; import { makeCaseCache } from '../../case_cache.js'; import { abstractFloatShaderBuilder, @@ -100,19 +99,13 @@ function makeVectorCaseWhole(kind: FPKind, v: readonly number[]): Case { return { input: toVector(v, fp.scalarBuilder), expected: ws }; } -const scalar_range = { - f32: fullF32Range(), - f16: fullF16Range(), - abstract: fullF64Range(), -}; - // Cases: [f32|f16|abstract]_[fract|whole] const scalar_cases = (['f32', 'f16', 'abstract'] as const) .flatMap(kind => (['whole', 'fract'] as const).map(portion => ({ [`${kind}_${portion}`]: () => { const makeCase = portion === 'whole' ? makeScalarCaseWhole : makeScalarCaseFract; - return scalar_range[kind].map(makeCase.bind(null, kind)); + return FP[kind].scalarRange().map(makeCase.bind(null, kind)); }, })) ) diff --git a/src/webgpu/shader/execution/expression/call/builtin/pack2x16float.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/pack2x16float.spec.ts index 790e54720c50..a0716038082f 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/pack2x16float.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/pack2x16float.spec.ts @@ -16,7 +16,7 @@ import { u32, vec2, } from '../../../../../util/conversion.js'; -import { cartesianProduct, fullF32Range, quantizeToF32 } from '../../../../../util/math.js'; +import { cartesianProduct, scalarF32Range, quantizeToF32 } from '../../../../../util/math.js'; import { makeCaseCache } from '../../case_cache.js'; import { allInputSources, Case, run } from '../../expression.js'; @@ -67,10 +67,10 @@ function generateCases(param0s: number[], param1s: number[], filter_undefined: b export const d = makeCaseCache('pack2x16float', { f32_const: () => { - return generateCases(fullF32Range(), fullF32Range(), true); + return generateCases(scalarF32Range(), scalarF32Range(), true); }, f32_non_const: () => { - return generateCases(fullF32Range(), fullF32Range(), false); + return generateCases(scalarF32Range(), scalarF32Range(), false); }, }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/pow.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/pow.spec.ts index f9b4fe1cfa28..6e682168de78 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/pow.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/pow.spec.ts @@ -11,7 +11,6 @@ import { makeTestGroup } from '../../../../../../common/framework/test_group.js' import { GPUTest } from '../../../../../gpu_test.js'; import { TypeF32, TypeF16 } from '../../../../../util/conversion.js'; import { FP } from '../../../../../util/floating_point.js'; -import { fullF32Range, fullF16Range } from '../../../../../util/math.js'; import { makeCaseCache } from '../../case_cache.js'; import { allInputSources, run } from '../../expression.js'; @@ -19,40 +18,23 @@ import { builtin } from './builtin.js'; export const g = makeTestGroup(GPUTest); -export const d = makeCaseCache('pow', { - f32_const: () => { - return FP.f32.generateScalarPairToIntervalCases( - fullF32Range(), - fullF32Range(), - 'finite', - FP.f32.powInterval - ); - }, - f32_non_const: () => { - return FP.f32.generateScalarPairToIntervalCases( - fullF32Range(), - fullF32Range(), - 'unfiltered', - FP.f32.powInterval - ); - }, - f16_const: () => { - return FP.f16.generateScalarPairToIntervalCases( - fullF16Range(), - fullF16Range(), - 'finite', - FP.f16.powInterval - ); - }, - f16_non_const: () => { - return FP.f16.generateScalarPairToIntervalCases( - fullF16Range(), - fullF16Range(), - 'unfiltered', - FP.f16.powInterval - ); - }, -}); +// Cases: [f32|f16]_[non_]const +const cases = (['f32', 'f16'] as const) + .flatMap(trait => + ([true, false] as const).map(nonConst => ({ + [`${trait}_${nonConst ? 'non_const' : 'const'}`]: () => { + return FP[trait].generateScalarPairToIntervalCases( + FP[trait].scalarRange(), + FP[trait].scalarRange(), + nonConst ? 'unfiltered' : 'finite', + FP[trait].powInterval + ); + }, + })) + ) + .reduce((a, b) => ({ ...a, ...b }), {}); + +export const d = makeCaseCache('pow', cases); g.test('abstract_float') .specURL('https://www.w3.org/TR/WGSL/#float-builtin-functions') diff --git a/src/webgpu/shader/execution/expression/call/builtin/quantizeToF16.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/quantizeToF16.spec.ts index b37d4c5afb81..d48dfddb09c5 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/quantizeToF16.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/quantizeToF16.spec.ts @@ -13,7 +13,7 @@ import { GPUTest } from '../../../../../gpu_test.js'; import { kValue } from '../../../../../util/constants.js'; import { TypeF32 } from '../../../../../util/conversion.js'; import { FP } from '../../../../../util/floating_point.js'; -import { fullF16Range, fullF32Range } from '../../../../../util/math.js'; +import { scalarF16Range, scalarF32Range } from '../../../../../util/math.js'; import { makeCaseCache } from '../../case_cache.js'; import { allInputSources, run } from '../../expression.js'; @@ -33,7 +33,7 @@ export const d = makeCaseCache('quantizeToF16', { kValue.f16.positive.subnormal.max, kValue.f16.positive.min, kValue.f16.positive.max, - ...fullF16Range(), + ...scalarF16Range(), ], 'finite', FP.f32.quantizeToF16Interval @@ -50,7 +50,7 @@ export const d = makeCaseCache('quantizeToF16', { kValue.f16.positive.subnormal.max, kValue.f16.positive.min, kValue.f16.positive.max, - ...fullF32Range(), + ...scalarF32Range(), ], 'unfiltered', FP.f32.quantizeToF16Interval diff --git a/src/webgpu/shader/execution/expression/call/builtin/radians.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/radians.spec.ts index 63ae45b656d2..0404ff3d6df4 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/radians.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/radians.spec.ts @@ -12,7 +12,6 @@ import { makeTestGroup } from '../../../../../../common/framework/test_group.js' import { GPUTest } from '../../../../../gpu_test.js'; import { TypeAbstractFloat, TypeF16, TypeF32 } from '../../../../../util/conversion.js'; import { FP } from '../../../../../util/floating_point.js'; -import { fullF16Range, fullF32Range } from '../../../../../util/math.js'; import { makeCaseCache } from '../../case_cache.js'; import { allInputSources, onlyConstInputSource, run } from '../../expression.js'; @@ -20,29 +19,20 @@ import { abstractBuiltin, builtin } from './builtin.js'; export const g = makeTestGroup(GPUTest); -export const d = makeCaseCache('radians', { - f32: () => { - return FP.f32.generateScalarToIntervalCases( - fullF32Range(), - 'unfiltered', - FP.f32.radiansInterval - ); - }, - f16: () => { - return FP.f16.generateScalarToIntervalCases( - fullF16Range(), - 'unfiltered', - FP.f16.radiansInterval - ); - }, - abstract: () => { - return FP.abstract.generateScalarToIntervalCases( - fullF16Range(), - 'unfiltered', - FP.abstract.radiansInterval - ); - }, -}); +// Cases: [f32|f16|abstract] +const cases = (['f32', 'f16', 'abstract'] as const) + .map(trait => ({ + [`${trait}`]: () => { + return FP[trait].generateScalarToIntervalCases( + FP[trait].scalarRange(), + 'unfiltered', + FP[trait].radiansInterval + ); + }, + })) + .reduce((a, b) => ({ ...a, ...b }), {}); + +export const d = makeCaseCache('radians', cases); g.test('abstract_float') .specURL('https://www.w3.org/TR/WGSL/#float-builtin-functions') diff --git a/src/webgpu/shader/execution/expression/call/builtin/refract.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/refract.spec.ts index 007b7be8c1bd..30253f9ce09c 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/refract.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/refract.spec.ts @@ -15,7 +15,6 @@ import { ROArrayArray } from '../../../../../../common/util/types.js'; import { GPUTest } from '../../../../../gpu_test.js'; import { toVector, TypeF32, TypeF16, TypeVec } from '../../../../../util/conversion.js'; import { FP, FPKind } from '../../../../../util/floating_point.js'; -import { sparseF32Range, sparseF16Range } from '../../../../../util/math.js'; import { makeCaseCache } from '../../case_cache.js'; import { allInputSources, Case, IntervalFilter, run } from '../../expression.js'; @@ -95,8 +94,7 @@ const cases = (['f32', 'f16'] as const) trait, FP[trait].sparseVectorRange(dim), FP[trait].sparseVectorRange(dim), - // NB: Refactor this when adding scalar ranges to FPTrait API - trait === 'f32' ? sparseF32Range() : sparseF16Range(), + FP[trait].sparseScalarRange(), nonConst ? 'unfiltered' : 'finite' ); }, diff --git a/src/webgpu/shader/execution/expression/call/builtin/round.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/round.spec.ts index fe81af632660..307490b835df 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/round.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/round.spec.ts @@ -14,7 +14,6 @@ import { makeTestGroup } from '../../../../../../common/framework/test_group.js' import { GPUTest } from '../../../../../gpu_test.js'; import { TypeF32, TypeF16, TypeAbstractFloat } from '../../../../../util/conversion.js'; import { FP } from '../../../../../util/floating_point.js'; -import { fullF32Range, fullF16Range, fullF64Range } from '../../../../../util/math.js'; import { makeCaseCache } from '../../case_cache.js'; import { allInputSources, onlyConstInputSource, run } from '../../expression.js'; @@ -22,38 +21,27 @@ import { abstractBuiltin, builtin } from './builtin.js'; export const g = makeTestGroup(GPUTest); -export const d = makeCaseCache('round', { - f32: () => { - return FP.f32.generateScalarToIntervalCases( - [ - 0x80000000, // https://github.com/gpuweb/cts/issues/2766, - ...fullF32Range(), - ], - 'unfiltered', - FP.f32.roundInterval - ); - }, - f16: () => { - return FP.f16.generateScalarToIntervalCases( - [ - 0x8000, // https://github.com/gpuweb/cts/issues/2766 - ...fullF16Range(), - ], - 'unfiltered', - FP.f16.roundInterval - ); - }, - abstract: () => { - return FP.abstract.generateScalarToIntervalCases( - [ - 0x8000_0000_0000_0000, // https://github.com/gpuweb/cts/issues/2766 - ...fullF64Range(), - ], - 'unfiltered', - FP.abstract.roundInterval - ); - }, -}); +// See https://github.com/gpuweb/cts/issues/2766 for details +const kIssue2766Value = { + abstract: 0x8000_0000_0000_0000, + f32: 0x8000_0000, + f16: 0x8000, +}; + +// Cases: [f32|f16|abstract] +const cases = (['f32', 'f16', 'abstract'] as const) + .map(trait => ({ + [`${trait}`]: () => { + return FP[trait].generateScalarToIntervalCases( + [kIssue2766Value[trait], ...FP[trait].scalarRange()], + 'unfiltered', + FP[trait].roundInterval + ); + }, + })) + .reduce((a, b) => ({ ...a, ...b }), {}); + +export const d = makeCaseCache('round', cases); g.test('abstract_float') .specURL('https://www.w3.org/TR/WGSL/#float-builtin-functions') diff --git a/src/webgpu/shader/execution/expression/call/builtin/saturate.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/saturate.spec.ts index 2f165029219c..429d5a322dae 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/saturate.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/saturate.spec.ts @@ -11,7 +11,7 @@ import { makeTestGroup } from '../../../../../../common/framework/test_group.js' import { GPUTest } from '../../../../../gpu_test.js'; import { TypeAbstractFloat, TypeF16, TypeF32 } from '../../../../../util/conversion.js'; import { FP } from '../../../../../util/floating_point.js'; -import { fullF16Range, fullF32Range, fullF64Range, linearRange } from '../../../../../util/math.js'; +import { linearRange } from '../../../../../util/math.js'; import { makeCaseCache } from '../../case_cache.js'; import { allInputSources, onlyConstInputSource, run } from '../../expression.js'; @@ -19,41 +19,20 @@ import { abstractBuiltin, builtin } from './builtin.js'; export const g = makeTestGroup(GPUTest); -export const d = makeCaseCache('saturate', { - f32: () => { - return FP.f32.generateScalarToIntervalCases( - [ - // Non-clamped values - ...linearRange(0.0, 1.0, 20), - ...fullF32Range(), - ], - 'unfiltered', - FP.f32.saturateInterval - ); - }, - f16: () => { - return FP.f16.generateScalarToIntervalCases( - [ - // Non-clamped values - ...linearRange(0.0, 1.0, 20), - ...fullF16Range(), - ], - 'unfiltered', - FP.f16.saturateInterval - ); - }, - abstract: () => { - return FP.abstract.generateScalarToIntervalCases( - [ - // Non-clamped values - ...linearRange(0.0, 1.0, 20), - ...fullF64Range(), - ], - 'unfiltered', - FP.abstract.saturateInterval - ); - }, -}); +// Cases: [f32|f16|abstract] +const cases = (['f32', 'f16', 'abstract'] as const) + .map(trait => ({ + [`${trait}`]: () => { + return FP[trait].generateScalarToIntervalCases( + [...linearRange(0.0, 1.0, 20), ...FP[trait].scalarRange()], + 'unfiltered', + FP[trait].saturateInterval + ); + }, + })) + .reduce((a, b) => ({ ...a, ...b }), {}); + +export const d = makeCaseCache('saturate', cases); g.test('abstract_float') .specURL('https://www.w3.org/TR/WGSL/#float-builtin-functions') diff --git a/src/webgpu/shader/execution/expression/call/builtin/sign.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/sign.spec.ts index a147acf6fb24..91d62148bf49 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/sign.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/sign.spec.ts @@ -17,12 +17,7 @@ import { TypeAbstractFloat, } from '../../../../../util/conversion.js'; import { FP } from '../../../../../util/floating_point.js'; -import { - fullF32Range, - fullF16Range, - fullI32Range, - fullF64Range, -} from '../../../../../util/math.js'; +import { fullI32Range } from '../../../../../util/math.js'; import { makeCaseCache } from '../../case_cache.js'; import { allInputSources, onlyConstInputSource, run } from '../../expression.js'; @@ -30,20 +25,21 @@ import { abstractBuiltin, builtin } from './builtin.js'; export const g = makeTestGroup(GPUTest); +// Cases: [f32|f16|abstract] +const fp_cases = (['f32', 'f16', 'abstract'] as const) + .map(trait => ({ + [`${trait}`]: () => { + return FP[trait].generateScalarToIntervalCases( + FP[trait].scalarRange(), + 'unfiltered', + FP[trait].signInterval + ); + }, + })) + .reduce((a, b) => ({ ...a, ...b }), {}); + export const d = makeCaseCache('sign', { - f32: () => { - return FP.f32.generateScalarToIntervalCases(fullF32Range(), 'unfiltered', FP.f32.signInterval); - }, - f16: () => { - return FP.f16.generateScalarToIntervalCases(fullF16Range(), 'unfiltered', FP.f16.signInterval); - }, - abstract_float: () => { - return FP.abstract.generateScalarToIntervalCases( - fullF64Range(), - 'unfiltered', - FP.abstract.signInterval - ); - }, + ...fp_cases, i32: () => fullI32Range().map(i => { const signFunc = (i: number): number => (i < 0 ? -1 : i > 0 ? 1 : 0); @@ -60,7 +56,7 @@ g.test('abstract_float') .combine('vectorize', [undefined, 2, 3, 4] as const) ) .fn(async t => { - const cases = await d.get('abstract_float'); + const cases = await d.get('abstract'); await run(t, abstractBuiltin('sign'), [TypeAbstractFloat], TypeAbstractFloat, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/sin.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/sin.spec.ts index 4ab3ae7a3d2c..6507d3aeddc1 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/sin.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/sin.spec.ts @@ -11,7 +11,7 @@ import { makeTestGroup } from '../../../../../../common/framework/test_group.js' import { GPUTest } from '../../../../../gpu_test.js'; import { TypeF32, TypeF16 } from '../../../../../util/conversion.js'; import { FP } from '../../../../../util/floating_point.js'; -import { fullF32Range, fullF16Range, linearRange } from '../../../../../util/math.js'; +import { linearRange } from '../../../../../util/math.js'; import { makeCaseCache } from '../../case_cache.js'; import { allInputSources, run } from '../../expression.js'; @@ -19,30 +19,24 @@ import { builtin } from './builtin.js'; export const g = makeTestGroup(GPUTest); -export const d = makeCaseCache('sin', { - f32: () => { - return FP.f32.generateScalarToIntervalCases( - [ - // Well-defined accuracy range - ...linearRange(-Math.PI, Math.PI, 1000), - ...fullF32Range(), - ], - 'unfiltered', - FP.f32.sinInterval - ); - }, - f16: () => { - return FP.f16.generateScalarToIntervalCases( - [ - // Well-defined accuracy range - ...linearRange(-Math.PI, Math.PI, 1000), - ...fullF16Range(), - ], - 'unfiltered', - FP.f16.sinInterval - ); - }, -}); +// Cases: [f32|f16] +const cases = (['f32', 'f16'] as const) + .map(trait => ({ + [`${trait}`]: () => { + return FP[trait].generateScalarToIntervalCases( + [ + // Well-defined accuracy range + ...linearRange(-Math.PI, Math.PI, 100), + ...FP[trait].scalarRange(), + ], + 'unfiltered', + FP[trait].sinInterval + ); + }, + })) + .reduce((a, b) => ({ ...a, ...b }), {}); + +export const d = makeCaseCache('sin', cases); g.test('abstract_float') .specURL('https://www.w3.org/TR/WGSL/#float-builtin-functions') diff --git a/src/webgpu/shader/execution/expression/call/builtin/sinh.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/sinh.spec.ts index d9b93a3dc81c..18268211d366 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/sinh.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/sinh.spec.ts @@ -11,7 +11,6 @@ import { makeTestGroup } from '../../../../../../common/framework/test_group.js' import { GPUTest } from '../../../../../gpu_test.js'; import { TypeF32, TypeF16 } from '../../../../../util/conversion.js'; import { FP } from '../../../../../util/floating_point.js'; -import { fullF32Range, fullF16Range } from '../../../../../util/math.js'; import { makeCaseCache } from '../../case_cache.js'; import { allInputSources, run } from '../../expression.js'; @@ -19,20 +18,22 @@ import { builtin } from './builtin.js'; export const g = makeTestGroup(GPUTest); -export const d = makeCaseCache('sinh', { - f32_const: () => { - return FP.f32.generateScalarToIntervalCases(fullF32Range(), 'finite', FP.f32.sinhInterval); - }, - f32_non_const: () => { - return FP.f32.generateScalarToIntervalCases(fullF32Range(), 'unfiltered', FP.f32.sinhInterval); - }, - f16_const: () => { - return FP.f16.generateScalarToIntervalCases(fullF16Range(), 'finite', FP.f16.sinhInterval); - }, - f16_non_const: () => { - return FP.f16.generateScalarToIntervalCases(fullF16Range(), 'unfiltered', FP.f16.sinhInterval); - }, -}); +// Cases: [f32|f16]_[non_]const +const cases = (['f32', 'f16'] as const) + .flatMap(trait => + ([true, false] as const).map(nonConst => ({ + [`${trait}_${nonConst ? 'non_const' : 'const'}`]: () => { + return FP[trait].generateScalarToIntervalCases( + FP[trait].scalarRange(), + nonConst ? 'unfiltered' : 'finite', + FP[trait].sinhInterval + ); + }, + })) + ) + .reduce((a, b) => ({ ...a, ...b }), {}); + +export const d = makeCaseCache('sinh', cases); g.test('abstract_float') .specURL('https://www.w3.org/TR/WGSL/#float-builtin-functions') diff --git a/src/webgpu/shader/execution/expression/call/builtin/smoothstep.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/smoothstep.spec.ts index 20d2a4edbce0..fb6e166dacc4 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/smoothstep.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/smoothstep.spec.ts @@ -13,7 +13,6 @@ import { makeTestGroup } from '../../../../../../common/framework/test_group.js' import { GPUTest } from '../../../../../gpu_test.js'; import { TypeF32, TypeF16 } from '../../../../../util/conversion.js'; import { FP } from '../../../../../util/floating_point.js'; -import { sparseF32Range, sparseF16Range } from '../../../../../util/math.js'; import { makeCaseCache } from '../../case_cache.js'; import { allInputSources, run } from '../../expression.js'; @@ -21,44 +20,24 @@ import { builtin } from './builtin.js'; export const g = makeTestGroup(GPUTest); -export const d = makeCaseCache('smoothstep', { - f32_const: () => { - return FP.f32.generateScalarTripleToIntervalCases( - sparseF32Range(), - sparseF32Range(), - sparseF32Range(), - 'finite', - FP.f32.smoothStepInterval - ); - }, - f32_non_const: () => { - return FP.f32.generateScalarTripleToIntervalCases( - sparseF32Range(), - sparseF32Range(), - sparseF32Range(), - 'unfiltered', - FP.f32.smoothStepInterval - ); - }, - f16_const: () => { - return FP.f16.generateScalarTripleToIntervalCases( - sparseF16Range(), - sparseF16Range(), - sparseF16Range(), - 'finite', - FP.f16.smoothStepInterval - ); - }, - f16_non_const: () => { - return FP.f16.generateScalarTripleToIntervalCases( - sparseF16Range(), - sparseF16Range(), - sparseF16Range(), - 'unfiltered', - FP.f16.smoothStepInterval - ); - }, -}); +// Cases: [f32|f16]_[non_]const +const cases = (['f32', 'f16'] as const) + .flatMap(trait => + ([true, false] as const).map(nonConst => ({ + [`${trait}_${nonConst ? 'non_const' : 'const'}`]: () => { + return FP[trait].generateScalarTripleToIntervalCases( + FP[trait].sparseScalarRange(), + FP[trait].sparseScalarRange(), + FP[trait].sparseScalarRange(), + nonConst ? 'unfiltered' : 'finite', + FP[trait].smoothStepInterval + ); + }, + })) + ) + .reduce((a, b) => ({ ...a, ...b }), {}); + +export const d = makeCaseCache('smoothstep', cases); g.test('abstract_float') .specURL('https://www.w3.org/TR/WGSL/#float-builtin-functions') diff --git a/src/webgpu/shader/execution/expression/call/builtin/sqrt.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/sqrt.spec.ts index a092438043d5..4954ddf9ab51 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/sqrt.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/sqrt.spec.ts @@ -11,7 +11,6 @@ import { makeTestGroup } from '../../../../../../common/framework/test_group.js' import { GPUTest } from '../../../../../gpu_test.js'; import { TypeF32, TypeF16 } from '../../../../../util/conversion.js'; import { FP } from '../../../../../util/floating_point.js'; -import { fullF32Range, fullF16Range } from '../../../../../util/math.js'; import { makeCaseCache } from '../../case_cache.js'; import { allInputSources, run } from '../../expression.js'; @@ -19,20 +18,22 @@ import { builtin } from './builtin.js'; export const g = makeTestGroup(GPUTest); -export const d = makeCaseCache('sqrt', { - f32_const: () => { - return FP.f32.generateScalarToIntervalCases(fullF32Range(), 'finite', FP.f32.sqrtInterval); - }, - f32_non_const: () => { - return FP.f32.generateScalarToIntervalCases(fullF32Range(), 'unfiltered', FP.f32.sqrtInterval); - }, - f16_const: () => { - return FP.f16.generateScalarToIntervalCases(fullF16Range(), 'finite', FP.f16.sqrtInterval); - }, - f16_non_const: () => { - return FP.f16.generateScalarToIntervalCases(fullF16Range(), 'unfiltered', FP.f16.sqrtInterval); - }, -}); +// Cases: [f32|f16]_[non_]const +const cases = (['f32', 'f16'] as const) + .flatMap(trait => + ([true, false] as const).map(nonConst => ({ + [`${trait}_${nonConst ? 'non_const' : 'const'}`]: () => { + return FP[trait].generateScalarToIntervalCases( + FP[trait].scalarRange(), + nonConst ? 'unfiltered' : 'finite', + FP[trait].sqrtInterval + ); + }, + })) + ) + .reduce((a, b) => ({ ...a, ...b }), {}); + +export const d = makeCaseCache('sqrt', cases); g.test('abstract_float') .specURL('https://www.w3.org/TR/WGSL/#float-builtin-functions') diff --git a/src/webgpu/shader/execution/expression/call/builtin/step.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/step.spec.ts index 752e2676e651..2e8f7ce8a070 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/step.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/step.spec.ts @@ -12,7 +12,6 @@ import { GPUTest } from '../../../../../gpu_test.js'; import { anyOf } from '../../../../../util/compare.js'; import { TypeF32, TypeF16 } from '../../../../../util/conversion.js'; import { FP } from '../../../../../util/floating_point.js'; -import { fullF32Range, fullF16Range } from '../../../../../util/math.js'; import { makeCaseCache } from '../../case_cache.js'; import { allInputSources, Case, run } from '../../expression.js'; @@ -44,14 +43,18 @@ const makeCase = (trait: 'f32' | 'f16', edge: number, x: number): Case => { }; }; -export const d = makeCaseCache('step', { - f32: () => { - return fullF32Range().flatMap(edge => fullF32Range().map(x => makeCase('f32', edge, x))); - }, - f16: () => { - return fullF16Range().flatMap(edge => fullF16Range().map(x => makeCase('f16', edge, x))); - }, -}); +// Cases: [f32|f16] +const cases = (['f32', 'f16'] as const) + .map(trait => ({ + [`${trait}`]: () => { + return FP[trait] + .scalarRange() + .flatMap(edge => FP[trait].scalarRange().map(x => makeCase(trait, edge, x))); + }, + })) + .reduce((a, b) => ({ ...a, ...b }), {}); + +export const d = makeCaseCache('step', cases); g.test('abstract_float') .specURL('https://www.w3.org/TR/WGSL/#float-builtin-functions') diff --git a/src/webgpu/shader/execution/expression/call/builtin/tan.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/tan.spec.ts index be3bdee04662..b54f0b11052b 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/tan.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/tan.spec.ts @@ -11,7 +11,7 @@ import { makeTestGroup } from '../../../../../../common/framework/test_group.js' import { GPUTest } from '../../../../../gpu_test.js'; import { TypeF32, TypeF16 } from '../../../../../util/conversion.js'; import { FP } from '../../../../../util/floating_point.js'; -import { fullF32Range, fullF16Range, linearRange } from '../../../../../util/math.js'; +import { linearRange } from '../../../../../util/math.js'; import { makeCaseCache } from '../../case_cache.js'; import { allInputSources, run } from '../../expression.js'; @@ -19,30 +19,24 @@ import { builtin } from './builtin.js'; export const g = makeTestGroup(GPUTest); -export const d = makeCaseCache('tan', { - f32: () => { - return FP.f32.generateScalarToIntervalCases( - [ - // Defined accuracy range - ...linearRange(-Math.PI, Math.PI, 100), - ...fullF32Range(), - ], - 'unfiltered', - FP.f32.tanInterval - ); - }, - f16: () => { - return FP.f16.generateScalarToIntervalCases( - [ - // Defined accuracy range - ...linearRange(-Math.PI, Math.PI, 100), - ...fullF16Range(), - ], - 'unfiltered', - FP.f16.tanInterval - ); - }, -}); +// Cases: [f32|f16] +const cases = (['f32', 'f16'] as const) + .map(trait => ({ + [`${trait}`]: () => { + return FP[trait].generateScalarToIntervalCases( + [ + // Well-defined accuracy range + ...linearRange(-Math.PI, Math.PI, 100), + ...FP[trait].scalarRange(), + ], + 'unfiltered', + FP[trait].tanInterval + ); + }, + })) + .reduce((a, b) => ({ ...a, ...b }), {}); + +export const d = makeCaseCache('tan', cases); g.test('abstract_float') .specURL('https://www.w3.org/TR/WGSL/#float-builtin-functions') diff --git a/src/webgpu/shader/execution/expression/call/builtin/tanh.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/tanh.spec.ts index 3aca5b924bf2..426181e79b05 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/tanh.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/tanh.spec.ts @@ -11,7 +11,6 @@ import { makeTestGroup } from '../../../../../../common/framework/test_group.js' import { GPUTest } from '../../../../../gpu_test.js'; import { TypeF32, TypeF16 } from '../../../../../util/conversion.js'; import { FP } from '../../../../../util/floating_point.js'; -import { fullF32Range, fullF16Range } from '../../../../../util/math.js'; import { makeCaseCache } from '../../case_cache.js'; import { allInputSources, run } from '../../expression.js'; @@ -19,14 +18,20 @@ import { builtin } from './builtin.js'; export const g = makeTestGroup(GPUTest); -export const d = makeCaseCache('tanh', { - f32: () => { - return FP.f32.generateScalarToIntervalCases(fullF32Range(), 'unfiltered', FP.f32.tanhInterval); - }, - f16: () => { - return FP.f16.generateScalarToIntervalCases(fullF16Range(), 'unfiltered', FP.f16.tanhInterval); - }, -}); +// Cases: [f32|f16] +const cases = (['f32', 'f16'] as const) + .map(trait => ({ + [`${trait}`]: () => { + return FP[trait].generateScalarToIntervalCases( + FP[trait].scalarRange(), + 'unfiltered', + FP[trait].tanhInterval + ); + }, + })) + .reduce((a, b) => ({ ...a, ...b }), {}); + +export const d = makeCaseCache('tanh', cases); g.test('abstract_float') .specURL('https://www.w3.org/TR/WGSL/#float-builtin-functions') diff --git a/src/webgpu/shader/execution/expression/call/builtin/trunc.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/trunc.spec.ts index 63cd8470f556..ce885450b85f 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/trunc.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/trunc.spec.ts @@ -12,7 +12,6 @@ import { makeTestGroup } from '../../../../../../common/framework/test_group.js' import { GPUTest } from '../../../../../gpu_test.js'; import { TypeAbstractFloat, TypeF16, TypeF32 } from '../../../../../util/conversion.js'; import { FP } from '../../../../../util/floating_point.js'; -import { fullF32Range, fullF64Range } from '../../../../../util/math.js'; import { makeCaseCache } from '../../case_cache.js'; import { allInputSources, onlyConstInputSource, run } from '../../expression.js'; @@ -20,21 +19,20 @@ import { abstractBuiltin, builtin } from './builtin.js'; export const g = makeTestGroup(GPUTest); -export const d = makeCaseCache('trunc', { - f32: () => { - return FP.f32.generateScalarToIntervalCases(fullF32Range(), 'unfiltered', FP.f32.truncInterval); - }, - f16: () => { - return FP.f16.generateScalarToIntervalCases(fullF32Range(), 'unfiltered', FP.f16.truncInterval); - }, - abstract: () => { - return FP.abstract.generateScalarToIntervalCases( - fullF64Range(), - 'unfiltered', - FP.abstract.truncInterval - ); - }, -}); +// Cases: [f32|f16|abstract] +const cases = (['f32', 'f16', 'abstract'] as const) + .map(trait => ({ + [`${trait}`]: () => { + return FP[trait].generateScalarToIntervalCases( + FP[trait].scalarRange(), + 'unfiltered', + FP[trait].truncInterval + ); + }, + })) + .reduce((a, b) => ({ ...a, ...b }), {}); + +export const d = makeCaseCache('trunc', cases); g.test('abstract_float') .specURL('https://www.w3.org/TR/WGSL/#float-builtin-functions') diff --git a/src/webgpu/shader/execution/expression/unary/af_arithmetic.spec.ts b/src/webgpu/shader/execution/expression/unary/af_arithmetic.spec.ts index 182c0d76a979..1ab64eb62d51 100644 --- a/src/webgpu/shader/execution/expression/unary/af_arithmetic.spec.ts +++ b/src/webgpu/shader/execution/expression/unary/af_arithmetic.spec.ts @@ -6,7 +6,7 @@ import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; import { TypeAbstractFloat } from '../../../../util/conversion.js'; import { FP } from '../../../../util/floating_point.js'; -import { fullF64Range } from '../../../../util/math.js'; +import { scalarF64Range } from '../../../../util/math.js'; import { makeCaseCache } from '../case_cache.js'; import { onlyConstInputSource, run } from '../expression.js'; @@ -17,7 +17,7 @@ export const g = makeTestGroup(GPUTest); export const d = makeCaseCache('unary/af_arithmetic', { negation: () => { return FP.abstract.generateScalarToIntervalCases( - fullF64Range({ neg_norm: 250, neg_sub: 20, pos_sub: 20, pos_norm: 250 }), + scalarF64Range({ neg_norm: 250, neg_sub: 20, pos_sub: 20, pos_norm: 250 }), 'unfiltered', FP.abstract.negationInterval ); diff --git a/src/webgpu/shader/execution/expression/unary/af_assignment.spec.ts b/src/webgpu/shader/execution/expression/unary/af_assignment.spec.ts index 141d87d0f2d9..d59649bbd40a 100644 --- a/src/webgpu/shader/execution/expression/unary/af_assignment.spec.ts +++ b/src/webgpu/shader/execution/expression/unary/af_assignment.spec.ts @@ -7,7 +7,11 @@ import { GPUTest } from '../../../../gpu_test.js'; import { kValue } from '../../../../util/constants.js'; import { abstractFloat, TypeAbstractFloat, TypeF16, TypeF32 } from '../../../../util/conversion.js'; import { FP } from '../../../../util/floating_point.js'; -import { filteredF64Range, fullF64Range, isSubnormalNumberF64 } from '../../../../util/math.js'; +import { + limitedScalarF64Range, + scalarF64Range, + isSubnormalNumberF64, +} from '../../../../util/math.js'; import { reinterpretU64AsF64 } from '../../../../util/reinterpret.js'; import { makeCaseCache } from '../case_cache.js'; import { @@ -48,7 +52,7 @@ export const d = makeCaseCache('unary/af_assignment', { reinterpretU64AsF64(0xffef_ffff_ffff_ffffn), // largest magnitude negative normal reinterpretU64AsF64(0x7fef_ffff_ffff_ffffn), // largest magnitude positive normal // WebGPU implementation stressing values - ...fullF64Range(), + ...scalarF64Range(), ]; return inputs.map(f => { return { @@ -58,12 +62,12 @@ export const d = makeCaseCache('unary/af_assignment', { }); }, f32: () => { - return filteredF64Range(kValue.f32.negative.min, kValue.f32.positive.max).map(f => { + return limitedScalarF64Range(kValue.f32.negative.min, kValue.f32.positive.max).map(f => { return { input: abstractFloat(f), expected: FP.f32.correctlyRoundedInterval(f) }; }); }, f16: () => { - return filteredF64Range(kValue.f16.negative.min, kValue.f16.positive.max).map(f => { + return limitedScalarF64Range(kValue.f16.negative.min, kValue.f16.positive.max).map(f => { return { input: abstractFloat(f), expected: FP.f16.correctlyRoundedInterval(f) }; }); }, diff --git a/src/webgpu/shader/execution/expression/unary/bool_conversion.spec.ts b/src/webgpu/shader/execution/expression/unary/bool_conversion.spec.ts index 8fcfed339fb6..2d83a389cd49 100644 --- a/src/webgpu/shader/execution/expression/unary/bool_conversion.spec.ts +++ b/src/webgpu/shader/execution/expression/unary/bool_conversion.spec.ts @@ -19,8 +19,8 @@ import { u32, } from '../../../../util/conversion.js'; import { - fullF32Range, - fullF16Range, + scalarF32Range, + scalarF16Range, fullI32Range, fullU32Range, isSubnormalNumberF32, @@ -51,7 +51,7 @@ export const d = makeCaseCache('unary/bool_conversion', { }); }, f32: () => { - return fullF32Range().map(f => { + return scalarF32Range().map(f => { const expected: Scalar[] = []; if (f !== 0) { expected.push(bool(true)); @@ -63,7 +63,7 @@ export const d = makeCaseCache('unary/bool_conversion', { }); }, f16: () => { - return fullF16Range().map(f => { + return scalarF16Range().map(f => { const expected: Scalar[] = []; if (f !== 0) { expected.push(bool(true)); diff --git a/src/webgpu/shader/execution/expression/unary/f16_arithmetic.spec.ts b/src/webgpu/shader/execution/expression/unary/f16_arithmetic.spec.ts index 83d7579c077d..e96bb354db8f 100644 --- a/src/webgpu/shader/execution/expression/unary/f16_arithmetic.spec.ts +++ b/src/webgpu/shader/execution/expression/unary/f16_arithmetic.spec.ts @@ -6,7 +6,7 @@ import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; import { TypeF16 } from '../../../../util/conversion.js'; import { FP } from '../../../../util/floating_point.js'; -import { fullF16Range } from '../../../../util/math.js'; +import { scalarF16Range } from '../../../../util/math.js'; import { makeCaseCache } from '../case_cache.js'; import { allInputSources, run } from '../expression.js'; @@ -17,7 +17,7 @@ export const g = makeTestGroup(GPUTest); export const d = makeCaseCache('unary/f16_arithmetic', { negation: () => { return FP.f16.generateScalarToIntervalCases( - fullF16Range({ neg_norm: 250, neg_sub: 20, pos_sub: 20, pos_norm: 250 }), + scalarF16Range({ neg_norm: 250, neg_sub: 20, pos_sub: 20, pos_norm: 250 }), 'unfiltered', FP.f16.negationInterval ); diff --git a/src/webgpu/shader/execution/expression/unary/f16_conversion.spec.ts b/src/webgpu/shader/execution/expression/unary/f16_conversion.spec.ts index 9eb84f0270fc..a4ebeef5fe18 100644 --- a/src/webgpu/shader/execution/expression/unary/f16_conversion.spec.ts +++ b/src/webgpu/shader/execution/expression/unary/f16_conversion.spec.ts @@ -18,8 +18,8 @@ import { } from '../../../../util/conversion.js'; import { FP, FPInterval } from '../../../../util/floating_point.js'; import { - fullF32Range, - fullF16Range, + scalarF32Range, + scalarF16Range, fullI32Range, fullU32Range, sparseMatrixF32Range, @@ -108,21 +108,21 @@ export const d = makeCaseCache('unary/f16_conversion', { // Note that f32 values may be not exactly representable in f16 and/or out of range. f32_non_const: () => { return FP.f32.generateScalarToIntervalCases( - [...fullF32Range(), 65535.996, -65535.996], + [...scalarF32Range(), 65535.996, -65535.996], 'unfiltered', FP.f16.correctlyRoundedInterval ); }, f32_const: () => { return FP.f32.generateScalarToIntervalCases( - [...fullF32Range(), 65535.996, -65535.996], + [...scalarF32Range(), 65535.996, -65535.996], 'finite', FP.f16.correctlyRoundedInterval ); }, // All f16 values are exactly representable in f16. f16: () => { - return fullF16Range().map(f => { + return scalarF16Range().map(f => { return { input: f16(f), expected: FP.f16.correctlyRoundedInterval(f) }; }); }, diff --git a/src/webgpu/shader/execution/expression/unary/f32_arithmetic.spec.ts b/src/webgpu/shader/execution/expression/unary/f32_arithmetic.spec.ts index f53cff46d83f..305a7812dd13 100644 --- a/src/webgpu/shader/execution/expression/unary/f32_arithmetic.spec.ts +++ b/src/webgpu/shader/execution/expression/unary/f32_arithmetic.spec.ts @@ -6,7 +6,7 @@ import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; import { TypeF32 } from '../../../../util/conversion.js'; import { FP } from '../../../../util/floating_point.js'; -import { fullF32Range } from '../../../../util/math.js'; +import { scalarF32Range } from '../../../../util/math.js'; import { makeCaseCache } from '../case_cache.js'; import { allInputSources, run } from '../expression.js'; @@ -17,7 +17,7 @@ export const g = makeTestGroup(GPUTest); export const d = makeCaseCache('unary/f32_arithmetic', { negation: () => { return FP.f32.generateScalarToIntervalCases( - fullF32Range({ neg_norm: 250, neg_sub: 20, pos_sub: 20, pos_norm: 250 }), + scalarF32Range({ neg_norm: 250, neg_sub: 20, pos_sub: 20, pos_norm: 250 }), 'unfiltered', FP.f32.negationInterval ); 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 223b13c2d554..1aa0b3e4a51c 100644 --- a/src/webgpu/shader/execution/expression/unary/f32_conversion.spec.ts +++ b/src/webgpu/shader/execution/expression/unary/f32_conversion.spec.ts @@ -19,8 +19,8 @@ import { } from '../../../../util/conversion.js'; import { FP } from '../../../../util/floating_point.js'; import { - fullF32Range, - fullF16Range, + scalarF32Range, + scalarF16Range, fullI32Range, fullU32Range, sparseMatrixF32Range, @@ -87,13 +87,13 @@ export const d = makeCaseCache('unary/f32_conversion', { }); }, f32: () => { - return fullF32Range().map(f => { + return scalarF32Range().map(f => { return { input: f32(f), expected: FP.f32.correctlyRoundedInterval(f) }; }); }, // All f16 values are exactly representable in f32. f16: () => { - return fullF16Range().map(f => { + return scalarF16Range().map(f => { return { input: f16(f), expected: FP.f32.correctlyRoundedInterval(f) }; }); }, diff --git a/src/webgpu/shader/execution/expression/unary/i32_conversion.spec.ts b/src/webgpu/shader/execution/expression/unary/i32_conversion.spec.ts index a77aa0e4d345..92379f22c9cf 100644 --- a/src/webgpu/shader/execution/expression/unary/i32_conversion.spec.ts +++ b/src/webgpu/shader/execution/expression/unary/i32_conversion.spec.ts @@ -18,8 +18,8 @@ import { u32, } from '../../../../util/conversion.js'; import { - fullF32Range, - fullF16Range, + scalarF32Range, + scalarF16Range, fullI32Range, fullU32Range, quantizeToF32, @@ -51,7 +51,7 @@ export const d = makeCaseCache('unary/i32_conversion', { }); }, f32: () => { - return fullF32Range().map(f => { + return scalarF32Range().map(f => { // Handles zeros and subnormals if (Math.abs(f) < 1.0) { return { input: f32(f), expected: i32(0) }; @@ -81,7 +81,7 @@ export const d = makeCaseCache('unary/i32_conversion', { }, f16: () => { // Note that finite f16 values are always in range of i32. - return fullF16Range().map(f => { + return scalarF16Range().map(f => { // Handles zeros and subnormals if (Math.abs(f) < 1.0) { return { input: f16(f), expected: i32(0) }; diff --git a/src/webgpu/shader/execution/expression/unary/u32_conversion.spec.ts b/src/webgpu/shader/execution/expression/unary/u32_conversion.spec.ts index 87dc6e7a5df8..c469f262c93d 100644 --- a/src/webgpu/shader/execution/expression/unary/u32_conversion.spec.ts +++ b/src/webgpu/shader/execution/expression/unary/u32_conversion.spec.ts @@ -18,8 +18,8 @@ import { u32, } from '../../../../util/conversion.js'; import { - fullF32Range, - fullF16Range, + scalarF32Range, + scalarF16Range, fullI32Range, fullU32Range, quantizeToF32, @@ -51,7 +51,7 @@ export const d = makeCaseCache('unary/u32_conversion', { }); }, f32: () => { - return fullF32Range().map(f => { + return scalarF32Range().map(f => { // Handles zeros, subnormals, and negatives if (f < 1.0) { return { input: f32(f), expected: u32(0) }; @@ -77,7 +77,7 @@ export const d = makeCaseCache('unary/u32_conversion', { }, f16: () => { // Note that all positive finite f16 values are in range of u32. - return fullF16Range().map(f => { + return scalarF16Range().map(f => { // Handles zeros, subnormals, and negatives if (f < 1.0) { return { input: f16(f), expected: u32(0) }; diff --git a/src/webgpu/shader/validation/expression/call/builtin/const_override_validation.ts b/src/webgpu/shader/validation/expression/call/builtin/const_override_validation.ts index 86b88cb159dc..d4f1676e35fc 100644 --- a/src/webgpu/shader/validation/expression/call/builtin/const_override_validation.ts +++ b/src/webgpu/shader/validation/expression/call/builtin/const_override_validation.ts @@ -8,7 +8,12 @@ import { elementsOf, isAbstractType, } from '../../../../../util/conversion.js'; -import { fullF16Range, fullF32Range, fullF64Range, linearRange } from '../../../../../util/math.js'; +import { + scalarF16Range, + scalarF32Range, + scalarF64Range, + linearRange, +} from '../../../../../util/math.js'; import { ShaderValidationTest } from '../../../shader_validation_test.js'; /// A linear sweep between -2 to 2 @@ -166,17 +171,17 @@ export function fullRangeForType(type: Type, count?: number) { } switch (elementType(type)?.kind) { case 'abstract-float': - return fullF64Range({ + return scalarF64Range({ pos_sub: Math.ceil((count * 1) / 5), pos_norm: Math.ceil((count * 4) / 5), }); case 'f32': - return fullF32Range({ + return scalarF32Range({ pos_sub: Math.ceil((count * 1) / 5), pos_norm: Math.ceil((count * 4) / 5), }); case 'f16': - return fullF16Range({ + return scalarF16Range({ pos_sub: Math.ceil((count * 1) / 5), pos_norm: Math.ceil((count * 4) / 5), }); diff --git a/src/webgpu/util/floating_point.ts b/src/webgpu/util/floating_point.ts index 55b18bf02f22..2cfdb170a0fc 100644 --- a/src/webgpu/util/floating_point.ts +++ b/src/webgpu/util/floating_point.ts @@ -46,6 +46,12 @@ import { vectorF16Range, vectorF32Range, vectorF64Range, + scalarF32Range, + sparseScalarF32Range, + scalarF64Range, + sparseScalarF64Range, + scalarF16Range, + sparseScalarF16Range, } from './math.js'; /** Indicate the kind of WGSL floating point numbers being operated on */ @@ -1087,6 +1093,10 @@ export abstract class FPTraits { public abstract readonly oneULP: (target: number, mode?: FlushMode) => number; /** @returns a builder for converting numbers to Scalars */ public abstract readonly scalarBuilder: (n: number) => Scalar; + /** @returns a range of scalars for testing */ + public abstract scalarRange(): readonly number[]; + /** @returns a reduced range of scalars for testing */ + public abstract sparseScalarRange(): readonly number[]; /** @returns a range of dim element vectors for testing */ public abstract vectorRange(dim: number): ROArrayArray; /** @returns a reduced range of dim element vectors for testing */ @@ -4530,6 +4540,8 @@ class F32Traits extends FPTraits { public readonly flushSubnormal = flushSubnormalNumberF32; public readonly oneULP = oneULPF32; public readonly scalarBuilder = f32; + public readonly scalarRange = scalarF32Range; + public readonly sparseScalarRange = sparseScalarF32Range; public readonly vectorRange = vectorF32Range; public readonly sparseVectorRange = sparseVectorF32Range; @@ -5004,6 +5016,8 @@ class FPAbstractTraits extends FPTraits { unreachable(`'FPAbstractTraits.oneULP should never be called`); }; public readonly scalarBuilder = abstractFloat; + public readonly scalarRange = scalarF64Range; + public readonly sparseScalarRange = sparseScalarF64Range; public readonly vectorRange = vectorF64Range; public readonly sparseVectorRange = sparseVectorF64Range; @@ -5338,6 +5352,8 @@ class F16Traits extends FPTraits { public readonly flushSubnormal = flushSubnormalNumberF16; public readonly oneULP = oneULPF16; public readonly scalarBuilder = f16; + public readonly scalarRange = scalarF16Range; + public readonly sparseScalarRange = sparseScalarF16Range; public readonly vectorRange = vectorF16Range; public readonly sparseVectorRange = sparseVectorF16Range; diff --git a/src/webgpu/util/math.ts b/src/webgpu/util/math.ts index 0fbe390856d4..f063a60eb8b9 100644 --- a/src/webgpu/util/math.ts +++ b/src/webgpu/util/math.ts @@ -891,12 +891,12 @@ export function biasedRange(a: number, b: number, num_steps: number): readonly n * for a wide range of magnitudes to be generated, instead of being extremely biased towards the edges of the f32 range. * * This function is intended to provide dense coverage of the f32 range, for a minimal list of values to use to cover - * f32 behaviour, use sparseF32Range instead. + * f32 behaviour, use sparseScalarF32Range instead. * * @param counts structure param with 4 entries indicating the number of entries to be generated each region, entries * must be 0 or greater. */ -export function fullF32Range( +export function scalarF32Range( counts: { neg_norm?: number; neg_sub?: number; @@ -943,8 +943,8 @@ export function fullF32Range( * @param low the lowest f32 value to permit when filtered * @param high the highest f32 value to permit when filtered */ -export function sourceFilteredF32Range(source: String, low: number, high: number): Array { - return fullF32Range().filter(x => source !== 'const' || (x >= low && x <= high)); +export function filteredScalarF32Range(source: String, low: number, high: number): Array { + return scalarF32Range().filter(x => source !== 'const' || (x >= low && x <= high)); } /** @@ -958,12 +958,12 @@ export function sourceFilteredF32Range(source: String, low: number, high: number * for a wide range of magnitudes to be generated, instead of being extremely biased towards the edges of the f16 range. * * This function is intended to provide dense coverage of the f16 range, for a minimal list of values to use to cover - * f16 behaviour, use sparseF16Range instead. + * f16 behaviour, use sparseScalarF16Range instead. * * @param counts structure param with 4 entries indicating the number of entries to be generated each region, entries * must be 0 or greater. */ -export function fullF16Range( +export function scalarF16Range( counts: { neg_norm?: number; neg_sub?: number; @@ -1009,12 +1009,12 @@ export function fullF16Range( * for a wide range of magnitudes to be generated, instead of being extremely biased towards the edges of the f64 range. * * This function is intended to provide dense coverage of the f64 range, for a minimal list of values to use to cover - * f64 behaviour, use sparseF64Range instead. + * f64 behaviour, use sparseScalarF64Range instead. * * @param counts structure param with 4 entries indicating the number of entries to be generated each region, entries * must be 0 or greater. */ -export function fullF64Range( +export function scalarF64Range( counts: { neg_norm?: number; neg_sub?: number; @@ -1065,7 +1065,7 @@ export function fullF64Range( * @param counts structure param with 4 entries indicating the number of entries * to be generated each region, entries must be 0 or greater. */ -export function filteredF64Range( +export function limitedScalarF64Range( begin: number, end: number, counts: { neg_norm?: number; neg_sub?: number; pos_sub: number; pos_norm: number } = { @@ -1299,18 +1299,18 @@ const kInterestingF32Values: readonly number[] = [ * specific values of interest. If there are known values of interest they * should be appended to this list in the test generation code. */ -export function sparseF32Range(): readonly number[] { +export function sparseScalarF32Range(): readonly number[] { return kInterestingF32Values; } const kVectorF32Values = { - 2: sparseF32Range().flatMap(f => [ + 2: sparseScalarF32Range().flatMap(f => [ [f, 1.0], [1.0, f], [f, -1.0], [-1.0, f], ]), - 3: sparseF32Range().flatMap(f => [ + 3: sparseScalarF32Range().flatMap(f => [ [f, 1.0, 2.0], [1.0, f, 2.0], [1.0, 2.0, f], @@ -1318,7 +1318,7 @@ const kVectorF32Values = { [-1.0, f, -2.0], [-1.0, -2.0, f], ]), - 4: sparseF32Range().flatMap(f => [ + 4: sparseScalarF32Range().flatMap(f => [ [f, 1.0, 2.0, 3.0], [1.0, f, 2.0, 3.0], [1.0, 2.0, f, 3.0], @@ -1349,13 +1349,13 @@ export function vectorF32Range(dim: number): ROArrayArray { } const kSparseVectorF32Values = { - 2: sparseF32Range().map((f, idx) => [idx % 2 === 0 ? f : idx, idx % 2 === 1 ? f : -idx]), - 3: sparseF32Range().map((f, idx) => [ + 2: sparseScalarF32Range().map((f, idx) => [idx % 2 === 0 ? f : idx, idx % 2 === 1 ? f : -idx]), + 3: sparseScalarF32Range().map((f, idx) => [ idx % 3 === 0 ? f : idx, idx % 3 === 1 ? f : -idx, idx % 3 === 2 ? f : idx, ]), - 4: sparseF32Range().map((f, idx) => [ + 4: sparseScalarF32Range().map((f, idx) => [ idx % 4 === 0 ? f : idx, idx % 4 === 1 ? f : -idx, idx % 4 === 2 ? f : idx, @@ -1369,8 +1369,8 @@ const kSparseVectorF32Values = { * * This is an even more stripped down version of `vectorF32Range` for when * pairs of vectors are being tested. - * All of the interesting floats from sparseF32 are guaranteed to be tested, but - * not in every position. + * All of the interesting floats from sparseScalarF32 are guaranteed to be + * tested, but not in every position. */ export function sparseVectorF32Range(dim: number): ROArrayArray { assert( @@ -1480,16 +1480,16 @@ const kSparseMatrixF32Values = { }; /** - * Returns a minimal set of matrices, indexed by dimension containing interesting - * float values. + * Returns a minimal set of matrices, indexed by dimension containing + * interesting float values. * * This is the matrix analogue of `sparseVectorF32Range`, so it is producing a * minimal coverage set of matrices that test all of the interesting f32 values. * There is not a more expansive set of matrices, since matrices are even more * expensive than vectors for increasing runtime with coverage. * - * All of the interesting floats from sparseF32 are guaranteed to be tested, but - * not in every position. + * All of the interesting floats from sparseScalarF32 are guaranteed to be + * tested, but not in every position. */ export function sparseMatrixF32Range(c: number, r: number): ROArrayArrayArray { assert( @@ -1535,18 +1535,18 @@ const kInterestingF16Values: readonly number[] = [ * specific values of interest. If there are known values of interest they * should be appended to this list in the test generation code. */ -export function sparseF16Range(): readonly number[] { +export function sparseScalarF16Range(): readonly number[] { return kInterestingF16Values; } const kVectorF16Values = { - 2: sparseF16Range().flatMap(f => [ + 2: sparseScalarF16Range().flatMap(f => [ [f, 1.0], [1.0, f], [f, -1.0], [-1.0, f], ]), - 3: sparseF16Range().flatMap(f => [ + 3: sparseScalarF16Range().flatMap(f => [ [f, 1.0, 2.0], [1.0, f, 2.0], [1.0, 2.0, f], @@ -1554,7 +1554,7 @@ const kVectorF16Values = { [-1.0, f, -2.0], [-1.0, -2.0, f], ]), - 4: sparseF16Range().flatMap(f => [ + 4: sparseScalarF16Range().flatMap(f => [ [f, 1.0, 2.0, 3.0], [1.0, f, 2.0, 3.0], [1.0, 2.0, f, 3.0], @@ -1585,13 +1585,13 @@ export function vectorF16Range(dim: number): ROArrayArray { } const kSparseVectorF16Values = { - 2: sparseF16Range().map((f, idx) => [idx % 2 === 0 ? f : idx, idx % 2 === 1 ? f : -idx]), - 3: sparseF16Range().map((f, idx) => [ + 2: sparseScalarF16Range().map((f, idx) => [idx % 2 === 0 ? f : idx, idx % 2 === 1 ? f : -idx]), + 3: sparseScalarF16Range().map((f, idx) => [ idx % 3 === 0 ? f : idx, idx % 3 === 1 ? f : -idx, idx % 3 === 2 ? f : idx, ]), - 4: sparseF16Range().map((f, idx) => [ + 4: sparseScalarF16Range().map((f, idx) => [ idx % 4 === 0 ? f : idx, idx % 4 === 1 ? f : -idx, idx % 4 === 2 ? f : idx, @@ -1605,8 +1605,8 @@ const kSparseVectorF16Values = { * * This is an even more stripped down version of `vectorF16Range` for when * pairs of vectors are being tested. - * All of the interesting floats from sparseF16 are guaranteed to be tested, but - * not in every position. + * All of the interesting floats from sparseScalarF16 are guaranteed to be + * tested, but not in every position. */ export function sparseVectorF16Range(dim: number): ROArrayArray { assert( @@ -1724,7 +1724,7 @@ const kSparseMatrixF16Values = { * There is not a more expansive set of matrices, since matrices are even more * expensive than vectors for increasing runtime with coverage. * - * All of the interesting floats from sparseF16 are guaranteed to be tested, but + * All of the interesting floats from sparseScalarF16 are guaranteed to be tested, but * not in every position. */ export function sparseMatrixF16Range(c: number, r: number): ROArrayArray[] { @@ -1771,18 +1771,18 @@ const kInterestingF64Values: readonly number[] = [ * specific values of interest. If there are known values of interest they * should be appended to this list in the test generation code. */ -export function sparseF64Range(): readonly number[] { +export function sparseScalarF64Range(): readonly number[] { return kInterestingF64Values; } const kVectorF64Values = { - 2: sparseF64Range().flatMap(f => [ + 2: sparseScalarF64Range().flatMap(f => [ [f, 1.0], [1.0, f], [f, -1.0], [-1.0, f], ]), - 3: sparseF64Range().flatMap(f => [ + 3: sparseScalarF64Range().flatMap(f => [ [f, 1.0, 2.0], [1.0, f, 2.0], [1.0, 2.0, f], @@ -1790,7 +1790,7 @@ const kVectorF64Values = { [-1.0, f, -2.0], [-1.0, -2.0, f], ]), - 4: sparseF64Range().flatMap(f => [ + 4: sparseScalarF64Range().flatMap(f => [ [f, 1.0, 2.0, 3.0], [1.0, f, 2.0, 3.0], [1.0, 2.0, f, 3.0], @@ -1821,13 +1821,13 @@ export function vectorF64Range(dim: number): ROArrayArray { } const kSparseVectorF64Values = { - 2: sparseF64Range().map((f, idx) => [idx % 2 === 0 ? f : idx, idx % 2 === 1 ? f : -idx]), - 3: sparseF64Range().map((f, idx) => [ + 2: sparseScalarF64Range().map((f, idx) => [idx % 2 === 0 ? f : idx, idx % 2 === 1 ? f : -idx]), + 3: sparseScalarF64Range().map((f, idx) => [ idx % 3 === 0 ? f : idx, idx % 3 === 1 ? f : -idx, idx % 3 === 2 ? f : idx, ]), - 4: sparseF64Range().map((f, idx) => [ + 4: sparseScalarF64Range().map((f, idx) => [ idx % 4 === 0 ? f : idx, idx % 4 === 1 ? f : -idx, idx % 4 === 2 ? f : idx, @@ -1841,7 +1841,7 @@ const kSparseVectorF64Values = { * * This is an even more stripped down version of `vectorF64Range` for when * pairs of vectors are being tested. - * All the interesting floats from sparseF64 are guaranteed to be tested, but + * All the interesting floats from sparseScalarF64 are guaranteed to be tested, but * not in every position. */ export function sparseVectorF64Range(dim: number): ROArrayArray { @@ -1960,7 +1960,7 @@ const kSparseMatrixF64Values = { * There is not a more expansive set of matrices, since matrices are even more * expensive than vectors for increasing runtime with coverage. * - * All the interesting floats from sparseF64 are guaranteed to be tested, but + * All the interesting floats from sparseScalarF64 are guaranteed to be tested, but * not in every position. */ export function sparseMatrixF64Range(c: number, r: number): ROArrayArray[] {