diff --git a/src/resources/cache/hashes.json b/src/resources/cache/hashes.json index 6a616d571a9e..1bbb980a95fc 100644 --- a/src/resources/cache/hashes.json +++ b/src/resources/cache/hashes.json @@ -1,110 +1,110 @@ { - "webgpu/shader/execution/binary/af_addition.bin": "24160909", + "webgpu/shader/execution/binary/af_addition.bin": "2607cb36", "webgpu/shader/execution/binary/af_logical.bin": "ffb5a83f", - "webgpu/shader/execution/binary/af_division.bin": "c230ac78", - "webgpu/shader/execution/binary/af_matrix_addition.bin": "9079a042", - "webgpu/shader/execution/binary/af_matrix_subtraction.bin": "6b55102f", - "webgpu/shader/execution/binary/af_multiplication.bin": "4fc3b0d6", - "webgpu/shader/execution/binary/af_remainder.bin": "366caec6", - "webgpu/shader/execution/binary/af_subtraction.bin": "49a16db4", - "webgpu/shader/execution/binary/f16_addition.bin": "3fb1ee09", + "webgpu/shader/execution/binary/af_division.bin": "9642be53", + "webgpu/shader/execution/binary/af_matrix_addition.bin": "28783339", + "webgpu/shader/execution/binary/af_matrix_subtraction.bin": "fd58a70a", + "webgpu/shader/execution/binary/af_multiplication.bin": "48fb6954", + "webgpu/shader/execution/binary/af_remainder.bin": "31290507", + "webgpu/shader/execution/binary/af_subtraction.bin": "aa7a977f", + "webgpu/shader/execution/binary/f16_addition.bin": "8dee9967", "webgpu/shader/execution/binary/f16_logical.bin": "65cdc6f", - "webgpu/shader/execution/binary/f16_division.bin": "1b5bd44a", - "webgpu/shader/execution/binary/f16_matrix_addition.bin": "fdea291a", - "webgpu/shader/execution/binary/f16_matrix_matrix_multiplication.bin": "e727482e", - "webgpu/shader/execution/binary/f16_matrix_scalar_multiplication.bin": "24d70bdd", - "webgpu/shader/execution/binary/f16_matrix_subtraction.bin": "7acd3c3b", - "webgpu/shader/execution/binary/f16_matrix_vector_multiplication.bin": "9e01e0cf", - "webgpu/shader/execution/binary/f16_multiplication.bin": "c24b705c", - "webgpu/shader/execution/binary/f16_remainder.bin": "2764c7e1", - "webgpu/shader/execution/binary/f16_subtraction.bin": "d4014a38", - "webgpu/shader/execution/binary/f32_addition.bin": "b6707259", + "webgpu/shader/execution/binary/f16_division.bin": "7642d7e5", + "webgpu/shader/execution/binary/f16_matrix_addition.bin": "451a2ca2", + "webgpu/shader/execution/binary/f16_matrix_matrix_multiplication.bin": "1a730f23", + "webgpu/shader/execution/binary/f16_matrix_scalar_multiplication.bin": "4e59085f", + "webgpu/shader/execution/binary/f16_matrix_subtraction.bin": "831ef7d9", + "webgpu/shader/execution/binary/f16_matrix_vector_multiplication.bin": "9956e198", + "webgpu/shader/execution/binary/f16_multiplication.bin": "f0593e54", + "webgpu/shader/execution/binary/f16_remainder.bin": "390d16d7", + "webgpu/shader/execution/binary/f16_subtraction.bin": "89d5e800", + "webgpu/shader/execution/binary/f32_addition.bin": "204ae10f", "webgpu/shader/execution/binary/f32_logical.bin": "d40c1c0", - "webgpu/shader/execution/binary/f32_division.bin": "e19e30a6", - "webgpu/shader/execution/binary/f32_matrix_addition.bin": "6a13d6d6", - "webgpu/shader/execution/binary/f32_matrix_matrix_multiplication.bin": "4c5cb0a2", - "webgpu/shader/execution/binary/f32_matrix_scalar_multiplication.bin": "6b00d17f", - "webgpu/shader/execution/binary/f32_matrix_subtraction.bin": "319d3ae1", - "webgpu/shader/execution/binary/f32_matrix_vector_multiplication.bin": "1c4893ca", - "webgpu/shader/execution/binary/f32_multiplication.bin": "f7dbbc8", - "webgpu/shader/execution/binary/f32_remainder.bin": "fb5dd3fe", - "webgpu/shader/execution/binary/f32_subtraction.bin": "aeaca568", + "webgpu/shader/execution/binary/f32_division.bin": "38119537", + "webgpu/shader/execution/binary/f32_matrix_addition.bin": "ee4f7b76", + "webgpu/shader/execution/binary/f32_matrix_matrix_multiplication.bin": "1145eefd", + "webgpu/shader/execution/binary/f32_matrix_scalar_multiplication.bin": "9b0de895", + "webgpu/shader/execution/binary/f32_matrix_subtraction.bin": "a1caf103", + "webgpu/shader/execution/binary/f32_matrix_vector_multiplication.bin": "63b9f583", + "webgpu/shader/execution/binary/f32_multiplication.bin": "8c039186", + "webgpu/shader/execution/binary/f32_remainder.bin": "7d54ad97", + "webgpu/shader/execution/binary/f32_subtraction.bin": "9080f361", "webgpu/shader/execution/binary/i32_arithmetic.bin": "90a3514a", "webgpu/shader/execution/binary/i32_comparison.bin": "840b09e6", "webgpu/shader/execution/binary/u32_arithmetic.bin": "e3f04e97", "webgpu/shader/execution/binary/u32_comparison.bin": "dc1398d3", - "webgpu/shader/execution/abs.bin": "2b663377", - "webgpu/shader/execution/acos.bin": "a888c67f", - "webgpu/shader/execution/acosh.bin": "5383658b", - "webgpu/shader/execution/asin.bin": "a580a322", - "webgpu/shader/execution/asinh.bin": "31388535", - "webgpu/shader/execution/atan.bin": "c6f4c771", - "webgpu/shader/execution/atan2.bin": "3b9a37a1", - "webgpu/shader/execution/atanh.bin": "7295a313", - "webgpu/shader/execution/bitcast.bin": "73e0bea6", - "webgpu/shader/execution/ceil.bin": "24bd6be9", - "webgpu/shader/execution/clamp.bin": "8ed55492", - "webgpu/shader/execution/cos.bin": "4d36fa0", - "webgpu/shader/execution/cosh.bin": "a7da3a3", - "webgpu/shader/execution/cross.bin": "6ce2660b", - "webgpu/shader/execution/degrees.bin": "53a0849", - "webgpu/shader/execution/determinant.bin": "873e78af", - "webgpu/shader/execution/distance.bin": "bfce09a0", - "webgpu/shader/execution/dot.bin": "566b6e55", - "webgpu/shader/execution/exp.bin": "d8142d49", - "webgpu/shader/execution/exp2.bin": "52a403d1", - "webgpu/shader/execution/faceForward.bin": "f90dacbe", - "webgpu/shader/execution/floor.bin": "c7465b11", - "webgpu/shader/execution/fma.bin": "db3497d4", - "webgpu/shader/execution/fract.bin": "e65c5bd1", - "webgpu/shader/execution/frexp.bin": "5ce112f4", - "webgpu/shader/execution/inverseSqrt.bin": "84ea0a57", - "webgpu/shader/execution/ldexp.bin": "9d11f120", - "webgpu/shader/execution/length.bin": "dd759736", - "webgpu/shader/execution/log.bin": "5f77a59d", - "webgpu/shader/execution/log2.bin": "57fff45e", - "webgpu/shader/execution/max.bin": "c7cdd54f", - "webgpu/shader/execution/min.bin": "422be325", - "webgpu/shader/execution/mix.bin": "957e7d92", - "webgpu/shader/execution/modf.bin": "946d1f4f", - "webgpu/shader/execution/normalize.bin": "2ac02e80", + "webgpu/shader/execution/abs.bin": "cbc5bb84", + "webgpu/shader/execution/acos.bin": "99826c48", + "webgpu/shader/execution/acosh.bin": "86faac44", + "webgpu/shader/execution/asin.bin": "1aa47c31", + "webgpu/shader/execution/asinh.bin": "3ca77d23", + "webgpu/shader/execution/atan.bin": "f3b4fad4", + "webgpu/shader/execution/atan2.bin": "695628c1", + "webgpu/shader/execution/atanh.bin": "ccac869a", + "webgpu/shader/execution/bitcast.bin": "a46c0f3c", + "webgpu/shader/execution/ceil.bin": "15ea076", + "webgpu/shader/execution/clamp.bin": "16a6107", + "webgpu/shader/execution/cos.bin": "8608aa24", + "webgpu/shader/execution/cosh.bin": "406887b3", + "webgpu/shader/execution/cross.bin": "ef98a37f", + "webgpu/shader/execution/degrees.bin": "a1f81fe8", + "webgpu/shader/execution/determinant.bin": "925aced0", + "webgpu/shader/execution/distance.bin": "1d1daa4b", + "webgpu/shader/execution/dot.bin": "5e618a78", + "webgpu/shader/execution/exp.bin": "c9ff3ee4", + "webgpu/shader/execution/exp2.bin": "124dd7fa", + "webgpu/shader/execution/faceForward.bin": "766871a0", + "webgpu/shader/execution/floor.bin": "bdbcec65", + "webgpu/shader/execution/fma.bin": "df9710d4", + "webgpu/shader/execution/fract.bin": "c6ac37ac", + "webgpu/shader/execution/frexp.bin": "4e41a6ad", + "webgpu/shader/execution/inverseSqrt.bin": "a874b8e0", + "webgpu/shader/execution/ldexp.bin": "52e686eb", + "webgpu/shader/execution/length.bin": "864e5694", + "webgpu/shader/execution/log.bin": "d86b6b5e", + "webgpu/shader/execution/log2.bin": "bb5ba2bc", + "webgpu/shader/execution/max.bin": "3e73f492", + "webgpu/shader/execution/min.bin": "6cc26be0", + "webgpu/shader/execution/mix.bin": "aca1fe65", + "webgpu/shader/execution/modf.bin": "e8dc88c2", + "webgpu/shader/execution/normalize.bin": "bd40a69", "webgpu/shader/execution/pack2x16float.bin": "d7ef3cf5", - "webgpu/shader/execution/pow.bin": "cd492166", - "webgpu/shader/execution/quantizeToF16.bin": "58bac06c", - "webgpu/shader/execution/radians.bin": "6ac08f50", - "webgpu/shader/execution/reflect.bin": "3c260554", - "webgpu/shader/execution/refract.bin": "7e952d7c", - "webgpu/shader/execution/round.bin": "f6b9bda1", - "webgpu/shader/execution/saturate.bin": "1c22f301", - "webgpu/shader/execution/sign.bin": "3ce55105", - "webgpu/shader/execution/sin.bin": "d48e7f2a", - "webgpu/shader/execution/sinh.bin": "f227c1d1", - "webgpu/shader/execution/smoothstep.bin": "6bdb4309", - "webgpu/shader/execution/sqrt.bin": "cd576d27", - "webgpu/shader/execution/step.bin": "dd584686", - "webgpu/shader/execution/tan.bin": "5ae50f61", - "webgpu/shader/execution/tanh.bin": "fe7a619d", - "webgpu/shader/execution/transpose.bin": "469edd7e", - "webgpu/shader/execution/trunc.bin": "8d3a05de", - "webgpu/shader/execution/unpack2x16float.bin": "e897c5ac", - "webgpu/shader/execution/unpack2x16snorm.bin": "450d5402", - "webgpu/shader/execution/unpack2x16unorm.bin": "306b3bf9", - "webgpu/shader/execution/unpack4x8snorm.bin": "fc1bd4c3", - "webgpu/shader/execution/unpack4x8unorm.bin": "763288cc", - "webgpu/shader/execution/unary/af_arithmetic.bin": "a39d4121", - "webgpu/shader/execution/unary/af_assignment.bin": "6ed540e8", + "webgpu/shader/execution/pow.bin": "a3f1d7bc", + "webgpu/shader/execution/quantizeToF16.bin": "cc9b060d", + "webgpu/shader/execution/radians.bin": "a4a45624", + "webgpu/shader/execution/reflect.bin": "f0edf7b6", + "webgpu/shader/execution/refract.bin": "b45fa1e3", + "webgpu/shader/execution/round.bin": "98a6ca02", + "webgpu/shader/execution/saturate.bin": "1724df20", + "webgpu/shader/execution/sign.bin": "c9304bbc", + "webgpu/shader/execution/sin.bin": "101ac9b0", + "webgpu/shader/execution/sinh.bin": "339cfa9d", + "webgpu/shader/execution/smoothstep.bin": "bd0ee34b", + "webgpu/shader/execution/sqrt.bin": "33a74294", + "webgpu/shader/execution/step.bin": "a546d1c7", + "webgpu/shader/execution/tan.bin": "98495e6c", + "webgpu/shader/execution/tanh.bin": "c8abf523", + "webgpu/shader/execution/transpose.bin": "48b9967b", + "webgpu/shader/execution/trunc.bin": "111d452f", + "webgpu/shader/execution/unpack2x16float.bin": "cafe4182", + "webgpu/shader/execution/unpack2x16snorm.bin": "9025c24a", + "webgpu/shader/execution/unpack2x16unorm.bin": "edec162d", + "webgpu/shader/execution/unpack4x8snorm.bin": "89fc1230", + "webgpu/shader/execution/unpack4x8unorm.bin": "6016b1d8", + "webgpu/shader/execution/unary/af_arithmetic.bin": "9f02dd09", + "webgpu/shader/execution/unary/af_assignment.bin": "2a53eabc", "webgpu/shader/execution/unary/bool_conversion.bin": "f37ea003", - "webgpu/shader/execution/unary/f16_arithmetic.bin": "9cadc739", - "webgpu/shader/execution/unary/f16_conversion.bin": "49c7b38e", - "webgpu/shader/execution/unary/f32_arithmetic.bin": "28da577a", - "webgpu/shader/execution/unary/f32_conversion.bin": "fcdfdd08", + "webgpu/shader/execution/unary/f16_arithmetic.bin": "5596e63b", + "webgpu/shader/execution/unary/f16_conversion.bin": "ae15a286", + "webgpu/shader/execution/unary/f32_arithmetic.bin": "1b8dfc4a", + "webgpu/shader/execution/unary/f32_conversion.bin": "3d408f29", "webgpu/shader/execution/unary/i32_arithmetic.bin": "25cf27d1", "webgpu/shader/execution/unary/i32_conversion.bin": "276dcf69", "webgpu/shader/execution/unary/u32_conversion.bin": "acac2172", "webgpu/shader/execution/unary/ai_assignment.bin": "c876d431", "webgpu/shader/execution/binary/ai_arithmetic.bin": "36a1d65b", "webgpu/shader/execution/unary/ai_arithmetic.bin": "89e34dcf", - "webgpu/shader/execution/binary/af_matrix_matrix_multiplication.bin": "3fd8797b", - "webgpu/shader/execution/binary/af_matrix_scalar_multiplication.bin": "bf99158a", - "webgpu/shader/execution/binary/af_matrix_vector_multiplication.bin": "8bcc7c30" + "webgpu/shader/execution/binary/af_matrix_matrix_multiplication.bin": "c6bc506b", + "webgpu/shader/execution/binary/af_matrix_scalar_multiplication.bin": "a77a12e3", + "webgpu/shader/execution/binary/af_matrix_vector_multiplication.bin": "fb71513a" } \ No newline at end of file diff --git a/src/resources/cache/webgpu/shader/execution/binary/af_division.bin b/src/resources/cache/webgpu/shader/execution/binary/af_division.bin index af690dcfb53f..656356d32e6a 100644 Binary files a/src/resources/cache/webgpu/shader/execution/binary/af_division.bin and b/src/resources/cache/webgpu/shader/execution/binary/af_division.bin differ diff --git a/src/resources/cache/webgpu/shader/execution/binary/af_matrix_matrix_multiplication.bin b/src/resources/cache/webgpu/shader/execution/binary/af_matrix_matrix_multiplication.bin index b710ae908402..58d0d40cb97d 100644 Binary files a/src/resources/cache/webgpu/shader/execution/binary/af_matrix_matrix_multiplication.bin and b/src/resources/cache/webgpu/shader/execution/binary/af_matrix_matrix_multiplication.bin differ diff --git a/src/resources/cache/webgpu/shader/execution/binary/af_matrix_vector_multiplication.bin b/src/resources/cache/webgpu/shader/execution/binary/af_matrix_vector_multiplication.bin index e57f91ffd980..545a5112cf0c 100644 Binary files a/src/resources/cache/webgpu/shader/execution/binary/af_matrix_vector_multiplication.bin and b/src/resources/cache/webgpu/shader/execution/binary/af_matrix_vector_multiplication.bin differ diff --git a/src/resources/cache/webgpu/shader/execution/binary/af_remainder.bin b/src/resources/cache/webgpu/shader/execution/binary/af_remainder.bin index b9cd253ac7ca..c45792abf49e 100644 Binary files a/src/resources/cache/webgpu/shader/execution/binary/af_remainder.bin and b/src/resources/cache/webgpu/shader/execution/binary/af_remainder.bin differ diff --git a/src/resources/cache/webgpu/shader/execution/cross.bin b/src/resources/cache/webgpu/shader/execution/cross.bin index 84bac5c8d6a1..c8ee9d3e1aa6 100644 Binary files a/src/resources/cache/webgpu/shader/execution/cross.bin and b/src/resources/cache/webgpu/shader/execution/cross.bin differ diff --git a/src/resources/cache/webgpu/shader/execution/degrees.bin b/src/resources/cache/webgpu/shader/execution/degrees.bin index 715e6b656f74..662558d78aca 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/determinant.bin b/src/resources/cache/webgpu/shader/execution/determinant.bin index d09c7df7e8aa..16d58c6db681 100644 Binary files a/src/resources/cache/webgpu/shader/execution/determinant.bin and b/src/resources/cache/webgpu/shader/execution/determinant.bin differ diff --git a/src/resources/cache/webgpu/shader/execution/dot.bin b/src/resources/cache/webgpu/shader/execution/dot.bin index 778ac0c1ad8e..13622a686b38 100644 Binary files a/src/resources/cache/webgpu/shader/execution/dot.bin and b/src/resources/cache/webgpu/shader/execution/dot.bin differ diff --git a/src/resources/cache/webgpu/shader/execution/fma.bin b/src/resources/cache/webgpu/shader/execution/fma.bin index db54353a5262..eb4cb9ebbe53 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/mix.bin b/src/resources/cache/webgpu/shader/execution/mix.bin index e6d92fc898d5..c42b2aa067e2 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/radians.bin b/src/resources/cache/webgpu/shader/execution/radians.bin index 63c7cc3ccd5b..f5285d108778 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/unittests/floating_point.spec.ts b/src/unittests/floating_point.spec.ts index 0c5c32ecd2e3..bf6678f89bf0 100644 --- a/src/unittests/floating_point.spec.ts +++ b/src/unittests/floating_point.spec.ts @@ -22,12 +22,7 @@ import { UnitTest } from './unit_test.js'; export const g = makeTestGroup(UnitTest); -/** - * For ULP purposes, abstract float behaves like f32, so need to swizzle it in - * for expectations. - */ const kFPTraitForULP = { - abstract: 'f32', f32: 'f32', f16: 'f16', } as const; @@ -2856,26 +2851,12 @@ const kDegreesIntervalCases = { { input: kValue.f16.positive.pi.three_quarters, expected: [kMinusOneULPFunctions['f16'](135), 135] }, { input: kValue.f16.positive.pi.whole, expected: [kMinusOneULPFunctions['f16'](180), 180] }, ] as ScalarToIntervalCase[], - abstract: [ - { input: kValue.f64.negative.pi.whole, expected: -180 }, - { input: kValue.f64.negative.pi.three_quarters, expected: -135 }, - { input: kValue.f64.negative.pi.half, expected: -90 }, - { input: kValue.f64.negative.pi.third, expected: kPlusOneULPFunctions['abstract'](-60) }, - { input: kValue.f64.negative.pi.quarter, expected: -45 }, - { input: kValue.f64.negative.pi.sixth, expected: kPlusOneULPFunctions['abstract'](-30) }, - { input: kValue.f64.positive.pi.sixth, expected: kMinusOneULPFunctions['abstract'](30) }, - { input: kValue.f64.positive.pi.quarter, expected: 45 }, - { input: kValue.f64.positive.pi.third, expected: kMinusOneULPFunctions['abstract'](60) }, - { input: kValue.f64.positive.pi.half, expected: 90 }, - { input: kValue.f64.positive.pi.three_quarters, expected: 135 }, - { input: kValue.f64.positive.pi.whole, expected: 180 }, - ] as ScalarToIntervalCase[], } as const; g.test('degreesInterval') .params(u => u - .combine('trait', ['f32', 'f16', 'abstract'] as const) + .combine('trait', ['f32', 'f16'] as const) .beginSubcases() .expandWithParams(p => { const trait = p.trait; @@ -3501,26 +3482,12 @@ const kRadiansIntervalCases = { { input: 135, expected: [kMinusOneULPFunctions['f16'](kValue.f16.positive.pi.three_quarters), kPlusOneULPFunctions['f16'](kValue.f16.positive.pi.three_quarters)] }, { input: 180, expected: [kMinusOneULPFunctions['f16'](kValue.f16.positive.pi.whole), kPlusOneULPFunctions['f16'](kValue.f16.positive.pi.whole)] }, ] as ScalarToIntervalCase[], - abstract: [ - { input: -180, expected: kValue.f64.negative.pi.whole }, - { input: -135, expected: kValue.f64.negative.pi.three_quarters }, - { input: -90, expected: kValue.f64.negative.pi.half }, - { input: -60, expected: kValue.f64.negative.pi.third }, - { input: -45, expected: kValue.f64.negative.pi.quarter }, - { input: -30, expected: kValue.f64.negative.pi.sixth }, - { input: 30, expected: kValue.f64.positive.pi.sixth }, - { input: 45, expected: kValue.f64.positive.pi.quarter }, - { input: 60, expected: kValue.f64.positive.pi.third }, - { input: 90, expected: kValue.f64.positive.pi.half }, - { input: 135, expected: kValue.f64.positive.pi.three_quarters }, - { input: 180, expected: kValue.f64.positive.pi.whole }, - ] as ScalarToIntervalCase[], } as const; g.test('radiansInterval') .params(u => u - .combine('trait', ['f32', 'f16', 'abstract'] as const) + .combine('trait', ['f32', 'f16'] as const) .beginSubcases() .expandWithParams(p => { const trait = p.trait; @@ -4392,13 +4359,10 @@ const kDivisionInterval64BitsNormalCases = { g.test('divisionInterval') .params(u => u - .combine('trait', ['abstract', 'f32', 'f16'] as const) + .combine('trait', ['f32', 'f16'] as const) .beginSubcases() .expandWithParams(p => { - // This is a ULP based interval, so abstract should behave like f32, so - // swizzling the trait as needed. - const trait = p.trait === 'abstract' ? 'f32' : p.trait; - const fp = FP[trait]; + const fp = FP[p.trait]; const constants = fp.constants(); // prettier-ignore return [ @@ -4415,7 +4379,7 @@ g.test('divisionInterval') { input: [-4, -2], expected: 2 }, // 64-bit normals that can not be exactly represented - ...kDivisionInterval64BitsNormalCases[trait], + ...kDivisionInterval64BitsNormalCases[p.trait], // Denominator out of range { input: [1, constants.positive.infinity], expected: kUnboundedEndpoints }, @@ -4431,10 +4395,7 @@ g.test('divisionInterval') }) ) .fn(t => { - // This is a ULP based interval, so abstract should behave like f32, so - // swizzling the trait as needed for calculating the expected result. - const trait = t.params.trait === 'abstract' ? 'f32' : t.params.trait; - const fp = FP[trait]; + const fp = FP[t.params.trait]; const error = (n: number): number => { return 2.5 * fp.oneULP(n); @@ -4442,7 +4403,6 @@ g.test('divisionInterval') const [x, y] = t.params.input; - // Do not swizzle here, so the correct implementation under test is called. const expected = FP[t.params.trait].toInterval(applyError(t.params.expected, error)); const got = FP[t.params.trait].divisionInterval(x, y); t.expect( @@ -4869,7 +4829,7 @@ const kRemainderCases = { g.test('remainderInterval') .params(u => u - .combine('trait', ['abstract', 'f32', 'f16'] as const) + .combine('trait', ['f32', 'f16'] as const) .beginSubcases() .expandWithParams(p => { const trait = kFPTraitForULP[p.trait]; @@ -5261,21 +5221,12 @@ const kFmaIntervalCases = { // minimum case: -1 * [subnormal ulp] + -1 * [subnormal ulp] rounded to [-2 * [subnormal ulp], 0], // maximum case: -0.0 + -0.0 = 0. { input: [kValue.f16.positive.subnormal.max, kValue.f16.negative.subnormal.min, kValue.f16.negative.subnormal.max], expected: [-2 * FP['f16'].oneULP(0, 'no-flush'), 0] }, ] as ScalarTripleToIntervalCase[], - abstract: [ - // These operations break down in the CTS, because `number` is a f64 under the hood, so precision is sometimes lost - // if intermediate results are closer to 0 than the smallest subnormal will be precisely 0. - // See https://github.com/gpuweb/cts/issues/2993 for details - { input: [kValue.f64.positive.subnormal.max, kValue.f64.positive.subnormal.max, 0], expected: 0 }, - { input: [kValue.f64.positive.subnormal.max, kValue.f64.positive.subnormal.max, kValue.f64.positive.subnormal.max], expected: [0, kValue.f64.positive.subnormal.max] }, - { input: [kValue.f64.positive.subnormal.max, kValue.f64.positive.subnormal.min, kValue.f64.negative.subnormal.max], expected: [kValue.f64.negative.subnormal.max, 0] }, - { input: [kValue.f64.positive.subnormal.max, kValue.f64.negative.subnormal.min, kValue.f64.negative.subnormal.max], expected: [kValue.f64.negative.subnormal.max, 0] }, - ] as ScalarTripleToIntervalCase[], } as const; g.test('fmaInterval') .params(u => u - .combine('trait', ['f32', 'f16', 'abstract'] as const) + .combine('trait', ['f32', 'f16'] as const) .beginSubcases() .expandWithParams(p => { const trait = FP[p.trait]; @@ -5390,40 +5341,12 @@ const kMixImpreciseIntervalCases = { { input: [kValue.f16.negative.min, 10.0, 0.5], expected: kUnboundedEndpoints }, { input: [kValue.f16.negative.min, -10.0, 0.5], expected: [-32768.0, -32752.0] }, ] as ScalarTripleToIntervalCase[], - abstract: [ - // [0.0, 1.0] cases - { input: [0.0, 1.0, 0.1], expected: 0.1 }, - { input: [0.0, 1.0, 0.9], expected: 0.9 }, - // [1.0, 0.0] cases - { input: [1.0, 0.0, 0.1], expected: 0.9 }, - { input: [1.0, 0.0, 0.9], expected: kMinusNULPFunctions['abstract'](0.1, 2) }, // This not being 0.1 is related to https://github.com/gpuweb/cts/issues/2993 - // [0.0, 10.0] cases - { input: [0.0, 10.0, 0.1], expected: 1 }, - { input: [0.0, 10.0, 0.9], expected: 9 }, - // [2.0, 10.0] cases - { input: [2.0, 10.0, 0.1], expected: 2.8 }, - { input: [2.0, 10.0, 0.9], expected: 9.2 }, - // [-1.0, 1.0] cases - { input: [-1.0, 1.0, 0.1], expected: -0.8 }, - { input: [-1.0, 1.0, 0.9], expected: 0.8 }, - - // Showing how precise and imprecise versions diff - // Note that this expectation is 0 in f64 as |10.0| is much smaller than - // |f64.negative.min|, so that 10 - f64.negative.min == -f64.negative.min - { input: [kValue.f64.negative.min, 10.0, 1.0], expected: 0 }, - // -10.0 is the same, much smaller than f64.negative.min - { input: [kValue.f64.negative.min, -10.0, 1.0], expected: 0 }, - { input: [kValue.f64.negative.min, 10.0, 5.0], expected: kUnboundedEndpoints }, - { input: [kValue.f64.negative.min, -10.0, 5.0], expected: kUnboundedEndpoints }, - { input: [kValue.f64.negative.min, 10.0, 0.5], expected: reinterpretU64AsF64(0xffdf_ffff_ffff_ffffn) }, - { input: [kValue.f64.negative.min, -10.0, 0.5], expected: reinterpretU64AsF64(0xffdf_ffff_ffff_ffffn) }, - ] as ScalarTripleToIntervalCase[], } as const; g.test('mixImpreciseInterval') .params(u => u - .combine('trait', ['f32', 'f16', 'abstract'] as const) + .combine('trait', ['f32', 'f16'] as const) .beginSubcases() .expandWithParams(p => { const trait = FP[p.trait]; @@ -5552,40 +5475,12 @@ const kMixPreciseIntervalCases = { // Intermediate OOB { input: [1.0, 2.0, kPlusOneULPFunctions['f16'](kValue.f16.positive.max / 2)], expected: kUnboundedEndpoints }, ] as ScalarTripleToIntervalCase[], - abstract: [ - // [0.0, 1.0] cases - { input: [0.0, 1.0, 0.1], expected: 0.1 }, - { input: [0.0, 1.0, 0.9], expected: 0.9 }, - // [1.0, 0.0] cases - { input: [1.0, 0.0, 0.1], expected: 0.9 }, - { input: [1.0, 0.0, 0.9], expected: kMinusNULPFunctions['abstract'](0.1, 2) }, // This not being 0.1 is related to https://github.com/gpuweb/cts/issues/2993 - // [0.0, 10.0] cases - { input: [0.0, 10.0, 0.1], expected: 1 }, - { input: [0.0, 10.0, 0.9], expected: 9 }, - // [2.0, 10.0] cases - { input: [2.0, 10.0, 0.1], expected: 2.8 }, - { input: [2.0, 10.0, 0.9], expected: 9.2 }, - // [-1.0, 1.0] cases - { input: [-1.0, 1.0, 0.1], expected: -0.8 }, - { input: [-1.0, 1.0, 0.9], expected: 0.8 }, - - // Showing how precise and imprecise versions diff - { input: [kValue.f64.negative.min, 10.0, 1.0], expected: 10.0 }, - { input: [kValue.f64.negative.min, -10.0, 1.0], expected: -10.0 }, - { input: [kValue.f64.negative.min, 10.0, 5.0], expected: kUnboundedEndpoints }, - { input: [kValue.f64.negative.min, -10.0, 5.0], expected: kUnboundedEndpoints }, - { input: [kValue.f64.negative.min, 10.0, 0.5], expected: reinterpretU64AsF64(0xffdf_ffff_ffff_ffffn) }, - { input: [kValue.f64.negative.min, -10.0, 0.5], expected: reinterpretU64AsF64(0xffdf_ffff_ffff_ffffn) }, - - // Intermediate OOB - { input: [1.0, 2.0, kPlusOneULPFunctions['abstract'](kValue.f64.positive.max / 2)], expected: kUnboundedEndpoints }, - ] as ScalarTripleToIntervalCase[], } as const; g.test('mixPreciseInterval') .params(u => u - .combine('trait', ['f32', 'f16', 'abstract'] as const) + .combine('trait', ['f32', 'f16'] as const) .beginSubcases() .expandWithParams(p => { const trait = FP[p.trait]; @@ -6133,17 +6028,12 @@ const kDotIntervalCases = { { input: [[kValue.f16.positive.max, 1.0, 2.0, 3.0], [-1.0, kValue.f16.positive.max, -2.0, -3.0]], expected: kUnboundedEndpoints }, { input: [[kValue.f16.positive.max, 1.0, 2.0, 3.0], [1.0, kValue.f16.negative.min, 2.0, 3.0]], expected: kUnboundedEndpoints }, ] as VectorPairToIntervalCase[], - abstract: [ - // See f32 for details - { input: [[kValue.f64.positive.max, 1.0, 2.0, 3.0], [-1.0, kValue.f64.positive.max, -2.0, -3.0]], expected: [-13, 0] }, - { input: [[kValue.f64.positive.max, 1.0, 2.0, 3.0], [1.0, kValue.f64.negative.min, 2.0, 3.0]], expected: [0, 13] }, - ] as VectorPairToIntervalCase[], } as const; g.test('dotInterval') .params(u => u - .combine('trait', ['f32', 'f16', 'abstract'] as const) + .combine('trait', ['f32', 'f16'] as const) .beginSubcases() .expandWithParams(p => { const trait = FP[p.trait]; @@ -6335,30 +6225,12 @@ const kCrossIntervalCases = { ] }, ] as VectorPairToVectorCase[], - abstract: [ - { input: [ - [kValue.f64.positive.subnormal.max, kValue.f64.negative.subnormal.max, kValue.f64.negative.subnormal.min], - [kValue.f64.negative.subnormal.min, kValue.f64.positive.subnormal.min, kValue.f64.negative.subnormal.max] - ], - expected: [0.0, 0.0, 0.0] - }, - { input: [ - [0.1, -0.1, -0.1], - [-0.1, 0.1, -0.1] - ], - expected: [ - reinterpretU64AsF64(0x3f94_7ae1_47ae_147cn), // ~0.02 - reinterpretU64AsF64(0x3f94_7ae1_47ae_147cn), // ~0.02 - 0.0 - ] - }, - ] as VectorPairToVectorCase[], } as const; g.test('crossInterval') .params(u => u - .combine('trait', ['f32', 'f16', 'abstract'] as const) + .combine('trait', ['f32', 'f16'] as const) .beginSubcases() .expandWithParams(p => { const trait = FP[p.trait]; @@ -6494,7 +6366,7 @@ interface MatrixToScalarCase { g.test('determinantInterval') .params(u => u - .combine('trait', ['f32', 'f16', 'abstract'] as const) + .combine('trait', ['f32', 'f16'] as const) .beginSubcases() .combineWithParams([ // Extreme values, i.e. subnormals, very large magnitudes, and those lead to @@ -7199,7 +7071,7 @@ g.test('subtractionMatrixMatrixInterval') g.test('multiplicationMatrixMatrixInterval') .params(u => u - .combine('trait', ['f32', 'f16', 'abstract'] as const) + .combine('trait', ['f32', 'f16'] as const) .beginSubcases() .combineWithParams([ // Only testing that different shapes of matrices are handled correctly @@ -7965,7 +7837,7 @@ interface MatrixVectorToVectorCase { g.test('multiplicationMatrixVectorInterval') .params(u => u - .combine('trait', ['f32', 'f16', 'abstract'] as const) + .combine('trait', ['f32', 'f16'] as const) .beginSubcases() .combineWithParams([ // Only testing that different shapes of matrices are handled correctly @@ -8082,7 +7954,7 @@ interface VectorMatrixToVectorCase { g.test('multiplicationVectorMatrixInterval') .params(u => u - .combine('trait', ['f32', 'f16', 'abstract'] as const) + .combine('trait', ['f32', 'f16'] as const) .beginSubcases() .combineWithParams([ // Only testing that different shapes of matrices are handled correctly diff --git a/src/webgpu/shader/execution/expression/binary/af_division.cache.ts b/src/webgpu/shader/execution/expression/binary/af_division.cache.ts index 5af293b3de28..ff2fb6a5780a 100644 --- a/src/webgpu/shader/execution/expression/binary/af_division.cache.ts +++ b/src/webgpu/shader/execution/expression/binary/af_division.cache.ts @@ -3,11 +3,13 @@ import { sparseScalarF64Range, sparseVectorF64Range } from '../../../../util/mat import { makeCaseCache } from '../case_cache.js'; const divisionVectorScalarInterval = (v: readonly number[], s: number): FPVector => { - return FP.abstract.toVector(v.map(e => FP.abstract.divisionInterval(e, s))); + // division has an ulp accuracy, so abstract is only expected to be as accurate as f32 + return FP.abstract.toVector(v.map(e => FP.f32.divisionInterval(e, s))); }; const divisionScalarVectorInterval = (s: number, v: readonly number[]): FPVector => { - return FP.abstract.toVector(v.map(e => FP.abstract.divisionInterval(s, e))); + // division has an ulp accuracy, so abstract is only expected to be as accurate as f32 + return FP.abstract.toVector(v.map(e => FP.f32.divisionInterval(s, e))); }; const scalar_cases = { @@ -16,7 +18,8 @@ const scalar_cases = { sparseScalarF64Range(), sparseScalarF64Range(), 'finite', - FP.abstract.divisionInterval + // division has an ulp accuracy, so abstract is only expected to be as accurate as f32 + FP.f32.divisionInterval ); }, }; diff --git a/src/webgpu/shader/execution/expression/binary/af_matrix_matrix_multiplication.cache.ts b/src/webgpu/shader/execution/expression/binary/af_matrix_matrix_multiplication.cache.ts index e539ee1db5da..78512fbd0d82 100644 --- a/src/webgpu/shader/execution/expression/binary/af_matrix_matrix_multiplication.cache.ts +++ b/src/webgpu/shader/execution/expression/binary/af_matrix_matrix_multiplication.cache.ts @@ -16,7 +16,8 @@ const mat_mat_cases = ([2, 3, 4] as const) sparseMatrixF64Range(k, rows), sparseMatrixF64Range(cols, k), 'finite', - FP.abstract.multiplicationMatrixMatrixInterval + // Matrix-matrix multiplication has an inherited accuracy, so abstract is only expected to be as accurate as f32 + FP.f32.multiplicationMatrixMatrixInterval ) ); }, diff --git a/src/webgpu/shader/execution/expression/binary/af_matrix_vector_multiplication.cache.ts b/src/webgpu/shader/execution/expression/binary/af_matrix_vector_multiplication.cache.ts index 1401428d3da0..4578eb0ce49b 100644 --- a/src/webgpu/shader/execution/expression/binary/af_matrix_vector_multiplication.cache.ts +++ b/src/webgpu/shader/execution/expression/binary/af_matrix_vector_multiplication.cache.ts @@ -15,7 +15,8 @@ const mat_vec_cases = ([2, 3, 4] as const) sparseMatrixF64Range(cols, rows), sparseVectorF64Range(cols), 'finite', - FP.abstract.multiplicationMatrixVectorInterval + // Matrix-vector multiplication has an inherited accuracy, so abstract is only expected to be as accurate as f32 + FP.f32.multiplicationMatrixVectorInterval ) ); }, @@ -35,7 +36,8 @@ const vec_mat_cases = ([2, 3, 4] as const) sparseVectorF64Range(rows), sparseMatrixF64Range(cols, rows), 'finite', - FP.abstract.multiplicationVectorMatrixInterval + // Vector-matrix multiplication has an inherited accuracy, so abstract is only expected to be as accurate as f32 + FP.f32.multiplicationVectorMatrixInterval ) ); }, diff --git a/src/webgpu/shader/execution/expression/binary/af_remainder.cache.ts b/src/webgpu/shader/execution/expression/binary/af_remainder.cache.ts index eba0a27760b0..4817298167ea 100644 --- a/src/webgpu/shader/execution/expression/binary/af_remainder.cache.ts +++ b/src/webgpu/shader/execution/expression/binary/af_remainder.cache.ts @@ -3,11 +3,13 @@ import { sparseScalarF64Range, sparseVectorF64Range } from '../../../../util/mat import { makeCaseCache } from '../case_cache.js'; const remainderVectorScalarInterval = (v: readonly number[], s: number): FPVector => { - return FP.abstract.toVector(v.map(e => FP.abstract.remainderInterval(e, s))); + // remainder has an inherited accuracy, so abstract is only expected to be as accurate as f32 + return FP.abstract.toVector(v.map(e => FP.f32.remainderInterval(e, s))); }; const remainderScalarVectorInterval = (s: number, v: readonly number[]): FPVector => { - return FP.abstract.toVector(v.map(e => FP.abstract.remainderInterval(s, e))); + // remainder has an inherited accuracy, so abstract is only expected to be as accurate as f32 + return FP.abstract.toVector(v.map(e => FP.f32.remainderInterval(s, e))); }; const scalar_cases = { @@ -16,7 +18,8 @@ const scalar_cases = { sparseScalarF64Range(), sparseScalarF64Range(), 'finite', - FP.abstract.remainderInterval + // remainder has an inherited accuracy, so abstract is only expected to be as accurate as f32 + FP.f32.remainderInterval ); }, }; diff --git a/src/webgpu/shader/execution/expression/call/builtin/cross.cache.ts b/src/webgpu/shader/execution/expression/call/builtin/cross.cache.ts index 74752d3afb26..396789b4ed64 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/cross.cache.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/cross.cache.ts @@ -14,7 +14,8 @@ const cases = (['f32', 'f16', 'abstract'] as const) FP[trait].vectorRange(3), FP[trait].vectorRange(3), nonConst ? 'unfiltered' : 'finite', - FP[trait].crossInterval + // cross has an inherited accuracy, so abstract is only expected to be as accurate as f32 + FP[trait !== 'abstract' ? trait : 'f32'].crossInterval ); }, })) diff --git a/src/webgpu/shader/execution/expression/call/builtin/degrees.cache.ts b/src/webgpu/shader/execution/expression/call/builtin/degrees.cache.ts index 2dbe8923c4cc..16abe41f3474 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/degrees.cache.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/degrees.cache.ts @@ -13,7 +13,8 @@ const cases = (['f32', 'f16', 'abstract'] as const) return FP[trait].generateScalarToIntervalCases( FP[trait].scalarRange(), nonConst ? 'unfiltered' : 'finite', - FP[trait].degreesInterval + // degrees has an inherited accuracy, so abstract is only expected to be as accurate as f32 + FP[trait !== 'abstract' ? trait : 'f32'].degreesInterval ); }, })) diff --git a/src/webgpu/shader/execution/expression/call/builtin/determinant.cache.ts b/src/webgpu/shader/execution/expression/call/builtin/determinant.cache.ts index 4eab44009abe..ccd073bce5ac 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/determinant.cache.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/determinant.cache.ts @@ -85,7 +85,8 @@ const abstract_cases = ([2, 3, 4] as const) return FP.abstract.generateMatrixToScalarCases( kDeterminantMatrixValues[dim], 'finite', - FP.abstract.determinantInterval + // determinant has an inherited accuracy, so abstract is only expected to be as accurate as f32 + FP.f32.determinantInterval ); }, })) diff --git a/src/webgpu/shader/execution/expression/call/builtin/dot.cache.ts b/src/webgpu/shader/execution/expression/call/builtin/dot.cache.ts index 06a4553a6363..6d1f22def137 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/dot.cache.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/dot.cache.ts @@ -75,7 +75,8 @@ const float_cases = (['f32', 'f16', 'abstract'] as const) N === 2 ? FP[trait].vectorRange(2) : FP[trait].sparseVectorRange(N), N === 2 ? FP[trait].vectorRange(2) : FP[trait].sparseVectorRange(N), nonConst ? 'unfiltered' : 'finite', - FP[trait].dotInterval + // dot has an inherited accuracy, so abstract is only expected to be as accurate as f32 + FP[trait !== 'abstract' ? trait : 'f32'].dotInterval ); }, })) diff --git a/src/webgpu/shader/execution/expression/call/builtin/fma.cache.ts b/src/webgpu/shader/execution/expression/call/builtin/fma.cache.ts index 0efa57f39c73..20a61ce83794 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/fma.cache.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/fma.cache.ts @@ -15,7 +15,8 @@ const cases = (['f32', 'f16', 'abstract'] as const) FP[trait].sparseScalarRange(), FP[trait].sparseScalarRange(), nonConst ? 'unfiltered' : 'finite', - FP[trait].fmaInterval + // fma has an inherited accuracy, so abstract is only expected to be as accurate as f32 + FP[trait !== 'abstract' ? trait : 'f32'].fmaInterval ); }, })) diff --git a/src/webgpu/shader/execution/expression/call/builtin/mix.cache.ts b/src/webgpu/shader/execution/expression/call/builtin/mix.cache.ts index 3f1de937b159..be221297b096 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/mix.cache.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/mix.cache.ts @@ -1,4 +1,5 @@ import { FP } from '../../../../../util/floating_point.js'; +import { selectNCases } from '../../case.js'; import { makeCaseCache } from '../../case_cache.js'; // Cases: [f32|f16|abstract]_[non_]const @@ -10,13 +11,15 @@ const scalar_cases = (['f32', 'f16', 'abstract'] as const) if (trait === 'abstract' && nonConst) { return []; } - return FP[trait].generateScalarTripleToIntervalCases( + const cases = FP[trait].generateScalarTripleToIntervalCases( FP[trait].sparseScalarRange(), FP[trait].sparseScalarRange(), FP[trait].sparseScalarRange(), nonConst ? 'unfiltered' : 'finite', - ...FP[trait].mixIntervals + // mix has an inherited accuracy, so abstract is only expected to be as accurate as f32 + ...FP[trait !== 'abstract' ? trait : 'f32'].mixIntervals ); + return selectNCases('mix_scalar', trait === 'abstract' ? 50 : cases.length, cases); }, })) ) @@ -32,13 +35,15 @@ const vec_scalar_cases = (['f32', 'f16', 'abstract'] as const) if (trait === 'abstract' && nonConst) { return []; } - return FP[trait].generateVectorPairScalarToVectorComponentWiseCase( + const cases = FP[trait].generateVectorPairScalarToVectorComponentWiseCase( FP[trait].sparseVectorRange(dim), FP[trait].sparseVectorRange(dim), FP[trait].sparseScalarRange(), nonConst ? 'unfiltered' : 'finite', - ...FP[trait].mixIntervals + // mix has an inherited accuracy, so abstract is only expected to be as accurate as f32 + ...FP[trait !== 'abstract' ? trait : 'f32'].mixIntervals ); + return selectNCases('mix_vector', trait === 'abstract' ? 50 : cases.length, cases); }, })) ) diff --git a/src/webgpu/shader/execution/expression/call/builtin/radians.cache.ts b/src/webgpu/shader/execution/expression/call/builtin/radians.cache.ts index e92b4970c499..8ed0fbbd2b94 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/radians.cache.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/radians.cache.ts @@ -7,8 +7,9 @@ const cases = (['f32', 'f16', 'abstract'] as const) [`${trait}`]: () => { return FP[trait].generateScalarToIntervalCases( FP[trait].scalarRange(), - 'unfiltered', - FP[trait].radiansInterval + trait !== 'abstract' ? 'unfiltered' : 'finite', + // radians has an inherited accuracy, so abstract is only expected to be as accurate as f32 + FP[trait !== 'abstract' ? trait : 'f32'].radiansInterval ); }, })) diff --git a/src/webgpu/util/floating_point.ts b/src/webgpu/util/floating_point.ts index 7887d82aaf70..5f1e14fad8e0 100644 --- a/src/webgpu/util/floating_point.ts +++ b/src/webgpu/util/floating_point.ts @@ -1713,7 +1713,6 @@ export abstract class FPTraits { ): Case | undefined { param0 = map2DArray(param0, this.quantize); param1 = map2DArray(param1, this.quantize); - const results = ops.map(o => o(param0, param1)); if (filter === 'finite' && results.some(m => m.some(c => c.some(r => !r.isFinite())))) { return undefined; @@ -2527,9 +2526,10 @@ export abstract class FPTraits { protected runMatrixToMatrixOp(m: FPMatrix, op: MatrixToMatrixOp): FPMatrix { const num_cols = m.length; const num_rows = m[0].length; - if (m.some(c => c.some(r => !r.isFinite()))) { - return this.constants().unboundedMatrix[num_cols][num_rows]; - } + + // Do not check for OOB inputs and exit early here, because the shape of + // the output matrix may be determined by the operation being run, + // i.e. transpose. const m_flat: readonly FPInterval[] = flatten2DArray(m); const m_values: ROArrayArray = cartesianProduct( @@ -3411,7 +3411,10 @@ export abstract class FPTraits { x: readonly number[] | readonly FPInterval[], y: readonly number[] | readonly FPInterval[] ): FPInterval { - assert(x.length === y.length, `dot not defined for vectors with different lengths`); + assert( + x.length === y.length, + `dot not defined for vectors with different lengths, x = ${x}, y = ${y}` + ); return this.runVectorPairToIntervalOp(this.toVector(x), this.toVector(y), this.DotIntervalOp); } @@ -5124,22 +5127,26 @@ class FPAbstractTraits extends FPTraits { public readonly clampIntervals = [this.clampMedianInterval, this.clampMinMaxInterval]; public readonly cosInterval = this.unimplementedScalarToInterval.bind(this, 'cosInterval'); public readonly coshInterval = this.unimplementedScalarToInterval.bind(this, 'coshInterval'); - public readonly crossInterval = this.crossIntervalImpl.bind(this); - public readonly degreesInterval = this.degreesIntervalImpl.bind(this); - public readonly determinantInterval = this.determinantIntervalImpl.bind(this); + public readonly crossInterval = this.unimplementedVectorPairToVector.bind(this, 'crossInterval'); + public readonly degreesInterval = this.unimplementedScalarToInterval.bind( + this, + 'degreesInterval' + ); + public readonly determinantInterval = this.unimplementedMatrixToInterval.bind( + this, + 'determinant' + ); public readonly distanceInterval = this.unimplementedDistance.bind(this); - public readonly divisionInterval = ( - x: number | FPInterval, - y: number | FPInterval - ): FPInterval => { - return this.toInterval(kF32Traits.divisionInterval(x, y)); - }; - public readonly dotInterval = this.dotIntervalImpl.bind(this); + public readonly divisionInterval = this.unimplementedScalarPairToInterval.bind( + this, + 'divisionInterval' + ); + public readonly dotInterval = this.unimplementedVectorPairToInterval.bind(this, 'dotInterval'); public readonly expInterval = this.unimplementedScalarToInterval.bind(this, 'expInterval'); public readonly exp2Interval = this.unimplementedScalarToInterval.bind(this, 'exp2Interval'); public readonly faceForwardIntervals = this.unimplementedFaceForward.bind(this); public readonly floorInterval = this.floorIntervalImpl.bind(this); - public readonly fmaInterval = this.fmaIntervalImpl.bind(this); + public readonly fmaInterval = this.unimplementedScalarTripleToInterval.bind(this, 'fmaInterval'); public readonly fractInterval = this.unimplementedScalarToInterval.bind(this, 'fractInterval'); public readonly inverseSqrtInterval = this.unimplementedScalarToInterval.bind( this, @@ -5154,36 +5161,49 @@ class FPAbstractTraits extends FPTraits { public readonly log2Interval = this.unimplementedScalarToInterval.bind(this, 'log2Interval'); public readonly maxInterval = this.maxIntervalImpl.bind(this); public readonly minInterval = this.minIntervalImpl.bind(this); - public readonly mixImpreciseInterval = this.mixImpreciseIntervalImpl.bind(this); - public readonly mixPreciseInterval = this.mixPreciseIntervalImpl.bind(this); + public readonly mixImpreciseInterval = this.unimplementedScalarTripleToInterval.bind( + this, + 'mixImpreciseInterval' + ); + public readonly mixPreciseInterval = this.unimplementedScalarTripleToInterval.bind( + this, + 'mixPreciseInterval' + ); public readonly mixIntervals = [this.mixImpreciseInterval, this.mixPreciseInterval]; public readonly modfInterval = this.modfIntervalImpl.bind(this); public readonly multiplicationInterval = this.multiplicationIntervalImpl.bind(this); - public readonly multiplicationMatrixMatrixInterval = - this.multiplicationMatrixMatrixIntervalImpl.bind(this); + public readonly multiplicationMatrixMatrixInterval = this.unimplementedMatrixPairToMatrix.bind( + this, + 'multiplicationMatrixMatrixInterval' + ); public readonly multiplicationMatrixScalarInterval = this.multiplicationMatrixScalarIntervalImpl.bind(this); public readonly multiplicationScalarMatrixInterval = this.multiplicationScalarMatrixIntervalImpl.bind(this); - public readonly multiplicationMatrixVectorInterval = - this.multiplicationMatrixVectorIntervalImpl.bind(this); - public readonly multiplicationVectorMatrixInterval = - this.multiplicationVectorMatrixIntervalImpl.bind(this); + public readonly multiplicationMatrixVectorInterval = this.unimplementedMatrixVectorToVector.bind( + this, + 'multiplicationMatrixVectorInterval' + ); + public readonly multiplicationVectorMatrixInterval = this.unimplementedVectorMatrixToVector.bind( + this, + 'multiplicationVectorMatrixInterval' + ); public readonly negationInterval = this.negationIntervalImpl.bind(this); public readonly normalizeInterval = this.unimplementedVectorToVector.bind( this, 'normalizeInterval' ); public readonly powInterval = this.unimplementedScalarPairToInterval.bind(this, 'powInterval'); - public readonly radiansInterval = this.radiansIntervalImpl.bind(this); + public readonly radiansInterval = this.unimplementedScalarToInterval.bind(this, 'radiansImpl'); public readonly reflectInterval = this.unimplementedVectorPairToVector.bind( this, 'reflectInterval' ); public readonly refractInterval = this.unimplementedRefract.bind(this); - public readonly remainderInterval = (x: number, y: number): FPInterval => { - return this.toInterval(kF32Traits.remainderInterval(x, y)); - }; + public readonly remainderInterval = this.unimplementedScalarPairToInterval.bind( + this, + 'remainderInterval' + ); public readonly roundInterval = this.roundIntervalImpl.bind(this); public readonly saturateInterval = this.saturateIntervalImpl.bind(this); public readonly signInterval = this.signIntervalImpl.bind(this);