diff --git a/src/resources/cache/hashes.json b/src/resources/cache/hashes.json index a825a4d57297..bcef9ec2c51c 100644 --- a/src/resources/cache/hashes.json +++ b/src/resources/cache/hashes.json @@ -1,107 +1,108 @@ { - "webgpu/shader/execution/binary/af_addition.bin": "d2a94254", - "webgpu/shader/execution/binary/af_logical.bin": "e32bdae7", - "webgpu/shader/execution/binary/af_division.bin": "998cb6fc", - "webgpu/shader/execution/binary/af_matrix_addition.bin": "496bd4ec", - "webgpu/shader/execution/binary/af_matrix_subtraction.bin": "dd4e9a4f", - "webgpu/shader/execution/binary/af_multiplication.bin": "e81deb2c", - "webgpu/shader/execution/binary/af_remainder.bin": "5aeed2e", - "webgpu/shader/execution/binary/af_subtraction.bin": "dc69ddc1", - "webgpu/shader/execution/binary/f16_addition.bin": "18815537", - "webgpu/shader/execution/binary/f16_logical.bin": "62ffb51f", - "webgpu/shader/execution/binary/f16_division.bin": "e4bf7770", - "webgpu/shader/execution/binary/f16_matrix_addition.bin": "ca4752e2", - "webgpu/shader/execution/binary/f16_matrix_matrix_multiplication.bin": "fec02413", - "webgpu/shader/execution/binary/f16_matrix_scalar_multiplication.bin": "1a7e0d08", - "webgpu/shader/execution/binary/f16_matrix_subtraction.bin": "8044743e", - "webgpu/shader/execution/binary/f16_matrix_vector_multiplication.bin": "ffb049e3", - "webgpu/shader/execution/binary/f16_multiplication.bin": "321b90f1", - "webgpu/shader/execution/binary/f16_remainder.bin": "bafa853", - "webgpu/shader/execution/binary/f16_subtraction.bin": "95a6af75", - "webgpu/shader/execution/binary/f32_addition.bin": "84b9178a", - "webgpu/shader/execution/binary/f32_logical.bin": "bc43ddfb", - "webgpu/shader/execution/binary/f32_division.bin": "2a526e73", - "webgpu/shader/execution/binary/f32_matrix_addition.bin": "23f30d9c", - "webgpu/shader/execution/binary/f32_matrix_matrix_multiplication.bin": "955042e6", - "webgpu/shader/execution/binary/f32_matrix_scalar_multiplication.bin": "61829041", - "webgpu/shader/execution/binary/f32_matrix_subtraction.bin": "2f60e0a", - "webgpu/shader/execution/binary/f32_matrix_vector_multiplication.bin": "3d6aba5e", - "webgpu/shader/execution/binary/f32_multiplication.bin": "2b4ddfb", - "webgpu/shader/execution/binary/f32_remainder.bin": "a3162fbe", - "webgpu/shader/execution/binary/f32_subtraction.bin": "5844472c", - "webgpu/shader/execution/binary/i32_arithmetic.bin": "77bd762d", - "webgpu/shader/execution/binary/i32_comparison.bin": "deaf3d06", - "webgpu/shader/execution/binary/u32_arithmetic.bin": "91ddc813", - "webgpu/shader/execution/binary/u32_comparison.bin": "82d7e10a", - "webgpu/shader/execution/abs.bin": "c2a08da0", - "webgpu/shader/execution/acos.bin": "ecb8f6e4", - "webgpu/shader/execution/acosh.bin": "e908c085", - "webgpu/shader/execution/asin.bin": "db1956dd", - "webgpu/shader/execution/asinh.bin": "d1c4370e", - "webgpu/shader/execution/atan.bin": "d32f84de", - "webgpu/shader/execution/atan2.bin": "c82ce2a9", - "webgpu/shader/execution/atanh.bin": "1d7fa05e", - "webgpu/shader/execution/bitcast.bin": "e6af5117", - "webgpu/shader/execution/ceil.bin": "6822702d", - "webgpu/shader/execution/clamp.bin": "2dcc8e33", - "webgpu/shader/execution/cos.bin": "1e4b5876", - "webgpu/shader/execution/cosh.bin": "88b43457", - "webgpu/shader/execution/cross.bin": "64b251e3", - "webgpu/shader/execution/degrees.bin": "ff5755de", - "webgpu/shader/execution/determinant.bin": "89ce1093", - "webgpu/shader/execution/distance.bin": "5694ecf1", - "webgpu/shader/execution/dot.bin": "60da4277", - "webgpu/shader/execution/exp.bin": "5ae18fc8", - "webgpu/shader/execution/exp2.bin": "ff8f009b", - "webgpu/shader/execution/faceForward.bin": "6ce196c1", - "webgpu/shader/execution/floor.bin": "addfc3d9", - "webgpu/shader/execution/fma.bin": "668f05ee", - "webgpu/shader/execution/fract.bin": "6d036c34", - "webgpu/shader/execution/frexp.bin": "3609ccd2", - "webgpu/shader/execution/inverseSqrt.bin": "b65957cd", - "webgpu/shader/execution/ldexp.bin": "99dcba57", - "webgpu/shader/execution/length.bin": "48edc788", - "webgpu/shader/execution/log.bin": "59d405b3", - "webgpu/shader/execution/log2.bin": "b897533e", - "webgpu/shader/execution/max.bin": "bb46b974", - "webgpu/shader/execution/min.bin": "e4e95641", - "webgpu/shader/execution/mix.bin": "4b781b3b", - "webgpu/shader/execution/modf.bin": "dda61537", - "webgpu/shader/execution/normalize.bin": "73a2bb69", - "webgpu/shader/execution/pack2x16float.bin": "d4a1d8f6", - "webgpu/shader/execution/pow.bin": "f4b1f7c6", - "webgpu/shader/execution/quantizeToF16.bin": "9632b1a3", - "webgpu/shader/execution/radians.bin": "838c408e", - "webgpu/shader/execution/reflect.bin": "401123c3", - "webgpu/shader/execution/refract.bin": "cf86546c", - "webgpu/shader/execution/round.bin": "d1cf1ebb", - "webgpu/shader/execution/saturate.bin": "6ecf8d76", - "webgpu/shader/execution/sign.bin": "f7757f54", - "webgpu/shader/execution/sin.bin": "aff5ff89", - "webgpu/shader/execution/sinh.bin": "10264f6", - "webgpu/shader/execution/smoothstep.bin": "cc165c8d", - "webgpu/shader/execution/sqrt.bin": "9288e28", - "webgpu/shader/execution/step.bin": "3e730ebc", - "webgpu/shader/execution/tan.bin": "b249b4ca", - "webgpu/shader/execution/tanh.bin": "add851dd", - "webgpu/shader/execution/transpose.bin": "ee64fd10", - "webgpu/shader/execution/trunc.bin": "b6c5fdcc", - "webgpu/shader/execution/unpack2x16float.bin": "46be8a57", - "webgpu/shader/execution/unpack2x16snorm.bin": "f2a50142", - "webgpu/shader/execution/unpack2x16unorm.bin": "6db99ed6", - "webgpu/shader/execution/unpack4x8snorm.bin": "4e88f425", - "webgpu/shader/execution/unpack4x8unorm.bin": "b818c7b", - "webgpu/shader/execution/unary/af_arithmetic.bin": "69e5897a", - "webgpu/shader/execution/unary/af_assignment.bin": "588f3b94", - "webgpu/shader/execution/unary/bool_conversion.bin": "7b22a4bf", - "webgpu/shader/execution/unary/f16_arithmetic.bin": "88bfdf25", - "webgpu/shader/execution/unary/f16_conversion.bin": "257326e2", - "webgpu/shader/execution/unary/f32_arithmetic.bin": "54315cef", - "webgpu/shader/execution/unary/f32_conversion.bin": "15bdedd7", - "webgpu/shader/execution/unary/i32_arithmetic.bin": "d8556f43", - "webgpu/shader/execution/unary/i32_complement.bin": "d044f52", - "webgpu/shader/execution/unary/i32_conversion.bin": "d1d94808", - "webgpu/shader/execution/unary/u32_complement.bin": "5458ccb1", - "webgpu/shader/execution/unary/u32_conversion.bin": "a7b4272e", - "webgpu/shader/execution/unary/ai_assignment.bin": "b15b5af8" + "webgpu/shader/execution/binary/af_addition.bin": "6295ae8d", + "webgpu/shader/execution/binary/af_logical.bin": "7b3b4609", + "webgpu/shader/execution/binary/af_division.bin": "6d08dc82", + "webgpu/shader/execution/binary/af_matrix_addition.bin": "fcb63375", + "webgpu/shader/execution/binary/af_matrix_subtraction.bin": "84a55db0", + "webgpu/shader/execution/binary/af_multiplication.bin": "6973ad39", + "webgpu/shader/execution/binary/af_remainder.bin": "64ce8104", + "webgpu/shader/execution/binary/af_subtraction.bin": "b2c3bacd", + "webgpu/shader/execution/binary/f16_addition.bin": "ec50b194", + "webgpu/shader/execution/binary/f16_logical.bin": "478641c", + "webgpu/shader/execution/binary/f16_division.bin": "b244992c", + "webgpu/shader/execution/binary/f16_matrix_addition.bin": "fe01bbc0", + "webgpu/shader/execution/binary/f16_matrix_matrix_multiplication.bin": "648ea38f", + "webgpu/shader/execution/binary/f16_matrix_scalar_multiplication.bin": "88f5f34d", + "webgpu/shader/execution/binary/f16_matrix_subtraction.bin": "d318acba", + "webgpu/shader/execution/binary/f16_matrix_vector_multiplication.bin": "a87759", + "webgpu/shader/execution/binary/f16_multiplication.bin": "37b44670", + "webgpu/shader/execution/binary/f16_remainder.bin": "27952a40", + "webgpu/shader/execution/binary/f16_subtraction.bin": "bebbb384", + "webgpu/shader/execution/binary/f32_addition.bin": "edfc25b3", + "webgpu/shader/execution/binary/f32_logical.bin": "68a96b19", + "webgpu/shader/execution/binary/f32_division.bin": "55a5ad13", + "webgpu/shader/execution/binary/f32_matrix_addition.bin": "95ab5a76", + "webgpu/shader/execution/binary/f32_matrix_matrix_multiplication.bin": "c58c207b", + "webgpu/shader/execution/binary/f32_matrix_scalar_multiplication.bin": "996185c6", + "webgpu/shader/execution/binary/f32_matrix_subtraction.bin": "4bb82fdf", + "webgpu/shader/execution/binary/f32_matrix_vector_multiplication.bin": "3c1824d", + "webgpu/shader/execution/binary/f32_multiplication.bin": "59d49dd9", + "webgpu/shader/execution/binary/f32_remainder.bin": "29fda04c", + "webgpu/shader/execution/binary/f32_subtraction.bin": "73fbf5dc", + "webgpu/shader/execution/binary/i32_arithmetic.bin": "646a8885", + "webgpu/shader/execution/binary/i32_comparison.bin": "d7b785fd", + "webgpu/shader/execution/binary/u32_arithmetic.bin": "567c4904", + "webgpu/shader/execution/binary/u32_comparison.bin": "edd2c4d", + "webgpu/shader/execution/abs.bin": "75cfc247", + "webgpu/shader/execution/acos.bin": "a9f2fa11", + "webgpu/shader/execution/acosh.bin": "14c2c311", + "webgpu/shader/execution/asin.bin": "99dcf943", + "webgpu/shader/execution/asinh.bin": "1db7a683", + "webgpu/shader/execution/atan.bin": "76983868", + "webgpu/shader/execution/atan2.bin": "45dcaeaa", + "webgpu/shader/execution/atanh.bin": "5514ca60", + "webgpu/shader/execution/bitcast.bin": "befdc87", + "webgpu/shader/execution/ceil.bin": "5d6cafdf", + "webgpu/shader/execution/clamp.bin": "b6146dbf", + "webgpu/shader/execution/cos.bin": "711b4fd4", + "webgpu/shader/execution/cosh.bin": "d9897d30", + "webgpu/shader/execution/cross.bin": "2a359c16", + "webgpu/shader/execution/degrees.bin": "d4ed9a44", + "webgpu/shader/execution/determinant.bin": "367920d5", + "webgpu/shader/execution/distance.bin": "5425926a", + "webgpu/shader/execution/dot.bin": "47f600ab", + "webgpu/shader/execution/exp.bin": "422bde4c", + "webgpu/shader/execution/exp2.bin": "ed8f1603", + "webgpu/shader/execution/faceForward.bin": "a8fe4a20", + "webgpu/shader/execution/floor.bin": "b4f14f3b", + "webgpu/shader/execution/fma.bin": "f60736ee", + "webgpu/shader/execution/fract.bin": "6b208a6d", + "webgpu/shader/execution/frexp.bin": "a10c6804", + "webgpu/shader/execution/inverseSqrt.bin": "22d094d6", + "webgpu/shader/execution/ldexp.bin": "85904868", + "webgpu/shader/execution/length.bin": "70b32f6", + "webgpu/shader/execution/log.bin": "4521ed5d", + "webgpu/shader/execution/log2.bin": "9a123e7", + "webgpu/shader/execution/max.bin": "ade14b73", + "webgpu/shader/execution/min.bin": "759505c4", + "webgpu/shader/execution/mix.bin": "1ad590ad", + "webgpu/shader/execution/modf.bin": "e78708e1", + "webgpu/shader/execution/normalize.bin": "21415be9", + "webgpu/shader/execution/pack2x16float.bin": "d07f345b", + "webgpu/shader/execution/pow.bin": "ae217c82", + "webgpu/shader/execution/quantizeToF16.bin": "3f8977d5", + "webgpu/shader/execution/radians.bin": "109797b3", + "webgpu/shader/execution/reflect.bin": "d6d70976", + "webgpu/shader/execution/refract.bin": "2f0a69bb", + "webgpu/shader/execution/round.bin": "4b744389", + "webgpu/shader/execution/saturate.bin": "15f37d3c", + "webgpu/shader/execution/sign.bin": "509816ea", + "webgpu/shader/execution/sin.bin": "e7d03236", + "webgpu/shader/execution/sinh.bin": "ca4fbb5", + "webgpu/shader/execution/smoothstep.bin": "6f3c506a", + "webgpu/shader/execution/sqrt.bin": "64c67887", + "webgpu/shader/execution/step.bin": "62dcbffb", + "webgpu/shader/execution/tan.bin": "de5a76d4", + "webgpu/shader/execution/tanh.bin": "36000b2f", + "webgpu/shader/execution/transpose.bin": "36d83e3c", + "webgpu/shader/execution/trunc.bin": "1aad5e1c", + "webgpu/shader/execution/unpack2x16float.bin": "41fbf466", + "webgpu/shader/execution/unpack2x16snorm.bin": "b2fde57", + "webgpu/shader/execution/unpack2x16unorm.bin": "9531a4f4", + "webgpu/shader/execution/unpack4x8snorm.bin": "39b662f2", + "webgpu/shader/execution/unpack4x8unorm.bin": "a7cd2c93", + "webgpu/shader/execution/unary/af_arithmetic.bin": "55c1671e", + "webgpu/shader/execution/unary/af_assignment.bin": "60be3db0", + "webgpu/shader/execution/unary/bool_conversion.bin": "f6dac757", + "webgpu/shader/execution/unary/f16_arithmetic.bin": "e762e795", + "webgpu/shader/execution/unary/f16_conversion.bin": "c568fe21", + "webgpu/shader/execution/unary/f32_arithmetic.bin": "7210a687", + "webgpu/shader/execution/unary/f32_conversion.bin": "1cc5f3cd", + "webgpu/shader/execution/unary/i32_arithmetic.bin": "9dfd1efe", + "webgpu/shader/execution/unary/i32_complement.bin": "405dfffa", + "webgpu/shader/execution/unary/i32_conversion.bin": "f2003321", + "webgpu/shader/execution/unary/u32_complement.bin": "987add5f", + "webgpu/shader/execution/unary/u32_conversion.bin": "3b3c5860", + "webgpu/shader/execution/unary/ai_assignment.bin": "bb95bb75", + "webgpu/shader/execution/binary/ai_arithmetic.bin": "ea3dd3e1" } \ No newline at end of file diff --git a/src/resources/cache/webgpu/shader/execution/binary/ai_arithmetic.bin b/src/resources/cache/webgpu/shader/execution/binary/ai_arithmetic.bin new file mode 100644 index 000000000000..3816f04d1fae Binary files /dev/null and b/src/resources/cache/webgpu/shader/execution/binary/ai_arithmetic.bin differ diff --git a/src/webgpu/listing_meta.json b/src/webgpu/listing_meta.json index a672a5c8750b..96c2ee50cf52 100644 --- a/src/webgpu/listing_meta.json +++ b/src/webgpu/listing_meta.json @@ -896,6 +896,9 @@ "webgpu:idl,constructable:gpu_errors:*": { "subcaseMS": 0.101 }, "webgpu:idl,constructable:pipeline_errors:*": { "subcaseMS": 0.101 }, "webgpu:idl,constructable:uncaptured_error_event:*": { "subcaseMS": 0.101 }, + "webgpu:shader,execution,expression,binary,ai_arithmetic:addition:*": { "subcaseMS": 0 }, + "webgpu:shader,execution,expression,binary,ai_arithmetic:addition_scalar_vector:*": { "subcaseMS": 0 }, + "webgpu:shader,execution,expression,binary,ai_arithmetic:addition_vector_scalar:*": { "subcaseMS": 0 }, "webgpu:shader,execution,expression,binary,af_addition:scalar:*": { "subcaseMS": 815.300 }, "webgpu:shader,execution,expression,binary,af_addition:scalar_vector:*": { "subcaseMS": 1803.434 }, "webgpu:shader,execution,expression,binary,af_addition:vector:*": { "subcaseMS": 719.600 }, 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 b34fb4f150dd..3b14897c2227 100644 --- a/src/webgpu/shader/execution/expression/binary/af_addition.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/af_addition.spec.ts @@ -8,7 +8,7 @@ import { TypeAbstractFloat, TypeVec } from '../../../../util/conversion.js'; import { onlyConstInputSource, run } from '../expression.js'; import { d } from './af_addition.cache.js'; -import { abstractBinary } from './binary.js'; +import { abstractFloatBinary } from './binary.js'; export const g = makeTestGroup(GPUTest); @@ -25,7 +25,7 @@ Accuracy: Correctly rounded const cases = await d.get('scalar'); await run( t, - abstractBinary('+'), + abstractFloatBinary('+'), [TypeAbstractFloat, TypeAbstractFloat], TypeAbstractFloat, t.params, @@ -48,7 +48,7 @@ Accuracy: Correctly rounded const cases = await d.get('scalar'); // Using vectorize to generate vector cases based on scalar cases await run( t, - abstractBinary('+'), + abstractFloatBinary('+'), [TypeAbstractFloat, TypeAbstractFloat], TypeAbstractFloat, t.params, @@ -70,7 +70,7 @@ Accuracy: Correctly rounded const cases = await d.get(`vec${dim}_scalar`); await run( t, - abstractBinary('+'), + abstractFloatBinary('+'), [TypeVec(dim, TypeAbstractFloat), TypeAbstractFloat], TypeVec(dim, TypeAbstractFloat), t.params, @@ -92,7 +92,7 @@ Accuracy: Correctly rounded const cases = await d.get(`scalar_vec${dim}`); await run( t, - abstractBinary('+'), + abstractFloatBinary('+'), [TypeAbstractFloat, TypeVec(dim, TypeAbstractFloat)], TypeVec(dim, TypeAbstractFloat), t.params, 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 1e5492a34d9c..5080e62264d2 100644 --- a/src/webgpu/shader/execution/expression/binary/af_division.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/af_division.spec.ts @@ -8,7 +8,7 @@ import { TypeAbstractFloat, TypeVec } from '../../../../util/conversion.js'; import { onlyConstInputSource, run } from '../expression.js'; import { d } from './af_division.cache.js'; -import { abstractBinary } from './binary.js'; +import { abstractFloatBinary } from './binary.js'; export const g = makeTestGroup(GPUTest); @@ -25,7 +25,7 @@ Accuracy: 2.5 ULP for |y| in the range [2^-126, 2^126] const cases = await d.get('scalar'); await run( t, - abstractBinary('/'), + abstractFloatBinary('/'), [TypeAbstractFloat, TypeAbstractFloat], TypeAbstractFloat, t.params, @@ -48,7 +48,7 @@ Accuracy: 2.5 ULP for |y| in the range [2^-126, 2^126] const cases = await d.get('scalar'); // Using vectorize to generate vector cases based on scalar cases await run( t, - abstractBinary('/'), + abstractFloatBinary('/'), [TypeAbstractFloat, TypeAbstractFloat], TypeAbstractFloat, t.params, @@ -70,7 +70,7 @@ Accuracy: Correctly rounded const cases = await d.get(`vec${dim}_scalar`); await run( t, - abstractBinary('/'), + abstractFloatBinary('/'), [TypeVec(dim, TypeAbstractFloat), TypeAbstractFloat], TypeVec(dim, TypeAbstractFloat), t.params, @@ -92,7 +92,7 @@ Accuracy: Correctly rounded const cases = await d.get(`scalar_vec${dim}`); await run( t, - abstractBinary('/'), + abstractFloatBinary('/'), [TypeAbstractFloat, TypeVec(dim, TypeAbstractFloat)], TypeVec(dim, TypeAbstractFloat), t.params, diff --git a/src/webgpu/shader/execution/expression/binary/af_matrix_addition.spec.ts b/src/webgpu/shader/execution/expression/binary/af_matrix_addition.spec.ts index 9f232c1ef6e6..7f6019f53127 100644 --- a/src/webgpu/shader/execution/expression/binary/af_matrix_addition.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/af_matrix_addition.spec.ts @@ -8,7 +8,7 @@ import { TypeAbstractFloat, TypeMat } from '../../../../util/conversion.js'; import { onlyConstInputSource, run } from '../expression.js'; import { d } from './af_matrix_addition.cache.js'; -import { abstractBinary } from './binary.js'; +import { abstractFloatBinary } from './binary.js'; export const g = makeTestGroup(GPUTest); @@ -32,7 +32,7 @@ Accuracy: Correctly rounded const cases = await d.get(`mat${cols}x${rows}`); await run( t, - abstractBinary('+'), + abstractFloatBinary('+'), [TypeMat(cols, rows, TypeAbstractFloat), TypeMat(cols, rows, TypeAbstractFloat)], TypeMat(cols, rows, TypeAbstractFloat), t.params, diff --git a/src/webgpu/shader/execution/expression/binary/af_matrix_subtraction.spec.ts b/src/webgpu/shader/execution/expression/binary/af_matrix_subtraction.spec.ts index 2697d1fe8cb0..4c6d1d423234 100644 --- a/src/webgpu/shader/execution/expression/binary/af_matrix_subtraction.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/af_matrix_subtraction.spec.ts @@ -8,7 +8,7 @@ import { TypeAbstractFloat, TypeMat } from '../../../../util/conversion.js'; import { onlyConstInputSource, run } from '../expression.js'; import { d } from './af_matrix_subtraction.cache.js'; -import { abstractBinary } from './binary.js'; +import { abstractFloatBinary } from './binary.js'; export const g = makeTestGroup(GPUTest); @@ -32,7 +32,7 @@ Accuracy: Correctly rounded const cases = await d.get(`mat${cols}x${rows}`); await run( t, - abstractBinary('-'), + abstractFloatBinary('-'), [TypeMat(cols, rows, TypeAbstractFloat), TypeMat(cols, rows, TypeAbstractFloat)], TypeMat(cols, rows, TypeAbstractFloat), t.params, 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 57beaca49ee8..57cf0dbc4768 100644 --- a/src/webgpu/shader/execution/expression/binary/af_multiplication.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/af_multiplication.spec.ts @@ -8,7 +8,7 @@ import { TypeAbstractFloat, TypeVec } from '../../../../util/conversion.js'; import { onlyConstInputSource, run } from '../expression.js'; import { d } from './af_multiplication.cache.js'; -import { abstractBinary } from './binary.js'; +import { abstractFloatBinary } from './binary.js'; export const g = makeTestGroup(GPUTest); @@ -25,7 +25,7 @@ Accuracy: Correctly rounded const cases = await d.get('scalar'); await run( t, - abstractBinary('*'), + abstractFloatBinary('*'), [TypeAbstractFloat, TypeAbstractFloat], TypeAbstractFloat, t.params, @@ -48,7 +48,7 @@ Accuracy: Correctly rounded const cases = await d.get('scalar'); // Using vectorize to generate vector cases based on scalar cases await run( t, - abstractBinary('*'), + abstractFloatBinary('*'), [TypeAbstractFloat, TypeAbstractFloat], TypeAbstractFloat, t.params, @@ -70,7 +70,7 @@ Accuracy: Correctly rounded const cases = await d.get(`vec${dim}_scalar`); await run( t, - abstractBinary('*'), + abstractFloatBinary('*'), [TypeVec(dim, TypeAbstractFloat), TypeAbstractFloat], TypeVec(dim, TypeAbstractFloat), t.params, @@ -92,7 +92,7 @@ Accuracy: Correctly rounded const cases = await d.get(`scalar_vec${dim}`); await run( t, - abstractBinary('*'), + abstractFloatBinary('*'), [TypeAbstractFloat, TypeVec(dim, TypeAbstractFloat)], TypeVec(dim, TypeAbstractFloat), t.params, 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 f53cb781b7cb..31a0991e02c4 100644 --- a/src/webgpu/shader/execution/expression/binary/af_remainder.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/af_remainder.spec.ts @@ -8,7 +8,7 @@ import { TypeAbstractFloat, TypeVec } from '../../../../util/conversion.js'; import { onlyConstInputSource, run } from '../expression.js'; import { d } from './af_remainder.cache.js'; -import { abstractBinary } from './binary.js'; +import { abstractFloatBinary } from './binary.js'; export const g = makeTestGroup(GPUTest); @@ -25,7 +25,7 @@ Accuracy: Derived from x - y * trunc(x/y) const cases = await d.get('scalar'); await run( t, - abstractBinary('%'), + abstractFloatBinary('%'), [TypeAbstractFloat, TypeAbstractFloat], TypeAbstractFloat, t.params, @@ -48,7 +48,7 @@ Accuracy: Derived from x - y * trunc(x/y) const cases = await d.get('scalar'); // Using vectorize to generate vector cases based on scalar cases await run( t, - abstractBinary('%'), + abstractFloatBinary('%'), [TypeAbstractFloat, TypeAbstractFloat], TypeAbstractFloat, t.params, @@ -70,7 +70,7 @@ Accuracy: Correctly rounded const cases = await d.get(`vec${dim}_scalar`); await run( t, - abstractBinary('%'), + abstractFloatBinary('%'), [TypeVec(dim, TypeAbstractFloat), TypeAbstractFloat], TypeVec(dim, TypeAbstractFloat), t.params, @@ -92,7 +92,7 @@ Accuracy: Correctly rounded const cases = await d.get(`scalar_vec${dim}`); await run( t, - abstractBinary('%'), + abstractFloatBinary('%'), [TypeAbstractFloat, TypeVec(dim, TypeAbstractFloat)], TypeVec(dim, TypeAbstractFloat), t.params, 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 b9e304fa134f..72004cfb1cee 100644 --- a/src/webgpu/shader/execution/expression/binary/af_subtraction.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/af_subtraction.spec.ts @@ -8,7 +8,7 @@ import { TypeAbstractFloat, TypeVec } from '../../../../util/conversion.js'; import { onlyConstInputSource, run } from '../expression.js'; import { d } from './af_subtraction.cache.js'; -import { abstractBinary } from './binary.js'; +import { abstractFloatBinary } from './binary.js'; export const g = makeTestGroup(GPUTest); @@ -25,7 +25,7 @@ Accuracy: Correctly rounded const cases = await d.get('scalar'); await run( t, - abstractBinary('-'), + abstractFloatBinary('-'), [TypeAbstractFloat, TypeAbstractFloat], TypeAbstractFloat, t.params, @@ -48,7 +48,7 @@ Accuracy: Correctly rounded const cases = await d.get('scalar'); // Using vectorize to generate vector cases based on scalar cases await run( t, - abstractBinary('-'), + abstractFloatBinary('-'), [TypeAbstractFloat, TypeAbstractFloat], TypeAbstractFloat, t.params, @@ -70,7 +70,7 @@ Accuracy: Correctly rounded const cases = await d.get(`vec${dim}_scalar`); await run( t, - abstractBinary('-'), + abstractFloatBinary('-'), [TypeVec(dim, TypeAbstractFloat), TypeAbstractFloat], TypeVec(dim, TypeAbstractFloat), t.params, @@ -92,7 +92,7 @@ Accuracy: Correctly rounded const cases = await d.get(`scalar_vec${dim}`); await run( t, - abstractBinary('-'), + abstractFloatBinary('-'), [TypeAbstractFloat, TypeVec(dim, TypeAbstractFloat)], TypeVec(dim, TypeAbstractFloat), t.params, diff --git a/src/webgpu/shader/execution/expression/binary/ai_arithmetic.cache.ts b/src/webgpu/shader/execution/expression/binary/ai_arithmetic.cache.ts new file mode 100644 index 000000000000..1ebd7646514a --- /dev/null +++ b/src/webgpu/shader/execution/expression/binary/ai_arithmetic.cache.ts @@ -0,0 +1,40 @@ +import { kValue } from '../../../../util/constants.js'; +import { sparseI64Range, vectorI64Range } from '../../../../util/math.js'; +import { + generateBinaryToI64Cases, + generateI64VectorBinaryToVectorCases, + generateVectorI64BinaryToVectorCases, +} from '../case.js'; +import { makeCaseCache } from '../case_cache.js'; + +function ai_add(x: bigint, y: bigint): bigint | undefined { + const result = x + y; + if (result > kValue.i64.positive.max || result < kValue.i64.negative.min) { + return undefined; + } + return result; +} + +export const d = makeCaseCache('binary/ai_arithmetic', { + addition: () => { + return generateBinaryToI64Cases(sparseI64Range(), sparseI64Range(), ai_add); + }, + addition_scalar_vector2: () => { + return generateI64VectorBinaryToVectorCases(sparseI64Range(), vectorI64Range(2), ai_add); + }, + addition_scalar_vector3: () => { + return generateI64VectorBinaryToVectorCases(sparseI64Range(), vectorI64Range(3), ai_add); + }, + addition_scalar_vector4: () => { + return generateI64VectorBinaryToVectorCases(sparseI64Range(), vectorI64Range(4), ai_add); + }, + addition_vector2_scalar: () => { + return generateVectorI64BinaryToVectorCases(vectorI64Range(2), sparseI64Range(), ai_add); + }, + addition_vector3_scalar: () => { + return generateVectorI64BinaryToVectorCases(vectorI64Range(3), sparseI64Range(), ai_add); + }, + addition_vector4_scalar: () => { + return generateVectorI64BinaryToVectorCases(vectorI64Range(4), sparseI64Range(), ai_add); + }, +}); diff --git a/src/webgpu/shader/execution/expression/binary/ai_arithmetic.spec.ts b/src/webgpu/shader/execution/expression/binary/ai_arithmetic.spec.ts new file mode 100644 index 000000000000..241ee80d6a27 --- /dev/null +++ b/src/webgpu/shader/execution/expression/binary/ai_arithmetic.spec.ts @@ -0,0 +1,71 @@ +export const description = ` +Execution Tests for the abstract int arithmetic binary expression operations +`; + +import { makeTestGroup } from '../../../../../common/framework/test_group.js'; +import { GPUTest } from '../../../../gpu_test.js'; +import { TypeAbstractInt, TypeVec } from '../../../../util/conversion.js'; +import { onlyConstInputSource, run } from '../expression.js'; + +import { d } from './ai_arithmetic.cache.js'; +import { abstractIntBinary } from './binary.js'; + +export const g = makeTestGroup(GPUTest); + +g.test('addition') + .specURL('https://www.w3.org/TR/WGSL/#floating-point-evaluation') + .desc( + ` +Expression: x + y +` + ) + .params(u => + u + .combine('inputSource', onlyConstInputSource) + .combine('vectorize', [undefined, 2, 3, 4] as const) + ) + .fn(async t => { + const cases = await d.get('addition'); + await run( + t, + abstractIntBinary('+'), + [TypeAbstractInt, TypeAbstractInt], + TypeAbstractInt, + t.params, + cases + ); + }); + +g.test('addition_scalar_vector') + .specURL('https://www.w3.org/TR/WGSL/#arithmetic-expr') + .desc( + ` +Expression: x + y +` + ) + .params(u => + u.combine('inputSource', onlyConstInputSource).combine('vectorize_rhs', [2, 3, 4] as const) + ) + .fn(async t => { + const vec_size = t.params.vectorize_rhs; + const vec_type = TypeVec(vec_size, TypeAbstractInt); + const cases = await d.get(`addition_scalar_vector${vec_size}`); + await run(t, abstractIntBinary('+'), [TypeAbstractInt, vec_type], vec_type, t.params, cases); + }); + +g.test('addition_vector_scalar') + .specURL('https://www.w3.org/TR/WGSL/#arithmetic-expr') + .desc( + ` +Expression: x + y +` + ) + .params(u => + u.combine('inputSource', onlyConstInputSource).combine('vectorize_lhs', [2, 3, 4] as const) + ) + .fn(async t => { + const vec_size = t.params.vectorize_lhs; + const vec_type = TypeVec(vec_size, TypeAbstractInt); + const cases = await d.get(`addition_vector${vec_size}_scalar`); + await run(t, abstractIntBinary('+'), [vec_type, TypeAbstractInt], vec_type, t.params, cases); + }); diff --git a/src/webgpu/shader/execution/expression/binary/binary.ts b/src/webgpu/shader/execution/expression/binary/binary.ts index f0b01b839b22..4df0c67d7883 100644 --- a/src/webgpu/shader/execution/expression/binary/binary.ts +++ b/src/webgpu/shader/execution/expression/binary/binary.ts @@ -3,6 +3,7 @@ import { basicExpressionBuilder, compoundAssignmentBuilder, abstractFloatShaderBuilder, + abstractIntShaderBuilder, } from '../expression.js'; /* @returns a ShaderBuilder that evaluates a binary operation */ @@ -16,6 +17,11 @@ export function compoundBinary(op: string): ShaderBuilder { } /* @returns a ShaderBuilder that evaluates a binary operation that returns AbstractFloats */ -export function abstractBinary(op: string): ShaderBuilder { +export function abstractFloatBinary(op: string): ShaderBuilder { return abstractFloatShaderBuilder(values => `(${values.map(v => `(${v})`).join(op)})`); } + +/* @returns a ShaderBuilder that evaluates a binary operation that returns AbstractFloats */ +export function abstractIntBinary(op: string): ShaderBuilder { + return abstractIntShaderBuilder(values => `(${values.map(v => `(${v})`).join(op)})`); +} diff --git a/src/webgpu/shader/execution/expression/case.ts b/src/webgpu/shader/execution/expression/case.ts index 65fd85d77bbc..b765e48eba17 100644 --- a/src/webgpu/shader/execution/expression/case.ts +++ b/src/webgpu/shader/execution/expression/case.ts @@ -1,14 +1,19 @@ import { ROArrayArray } from '../../../../common/util/types.js'; -import { ScalarBuilder, Value, Vector, i32, u32 } from '../../../util/conversion.js'; +import { ScalarBuilder, Value, Vector, i32, u32, abstractInt } from '../../../util/conversion.js'; import { QuantizeFunc, cartesianProduct, quantizeToI32, quantizeToU32, + quantizeToI64, } from '../../../util/math.js'; import { Expectation } from './expectation.js'; +function notUndefined(value: T | undefined): value is T { + return value !== undefined; +} + /** Case is a single expression test case. */ export type Case = { // The input value(s) @@ -21,11 +26,11 @@ export type Case = { export type CaseList = Array; /** - * A function that performs a binary operation on x and y, and returns the expected - * result. + * A function that performs a binary operation on x and y, and returns the + * expected result. */ -export interface BinaryOp { - (x: number, y: number): number | undefined; +export interface BinaryOp { + (x: T, y: T): T | undefined; } /** @@ -36,12 +41,12 @@ export interface BinaryOp { * @param quantize function to quantize all values in vectors and scalars * @param scalarize function to convert numbers to Scalars */ -function makeScalarVectorBinaryToVectorCase( - scalar: number, - vector: readonly number[], - op: BinaryOp, - quantize: QuantizeFunc, - scalarize: ScalarBuilder +function makeScalarVectorBinaryToVectorCase( + scalar: T, + vector: readonly T[], + op: BinaryOp, + quantize: QuantizeFunc, + scalarize: ScalarBuilder ): Case | undefined { scalar = quantize(scalar); vector = vector.map(quantize); @@ -51,7 +56,7 @@ function makeScalarVectorBinaryToVectorCase( } return { input: [scalarize(scalar), new Vector(vector.map(scalarize))], - expected: new Vector((result as readonly number[]).map(scalarize)), + expected: new Vector(result.filter(notUndefined).map(scalarize)), }; } @@ -63,23 +68,20 @@ function makeScalarVectorBinaryToVectorCase( * @param quantize function to quantize all values in vectors and scalars * @param scalarize function to convert numbers to Scalars */ -function generateScalarVectorBinaryToVectorCases( - scalars: readonly number[], - vectors: ROArrayArray, - op: BinaryOp, - quantize: QuantizeFunc, - scalarize: ScalarBuilder +function generateScalarVectorBinaryToVectorCases( + scalars: readonly T[], + vectors: ROArrayArray, + op: BinaryOp, + quantize: QuantizeFunc, + scalarize: ScalarBuilder ): Case[] { - const cases = new Array(); - scalars.forEach(s => { - vectors.forEach(v => { - const c = makeScalarVectorBinaryToVectorCase(s, v, op, quantize, scalarize); - if (c !== undefined) { - cases.push(c); - } - }); + return scalars.flatMap(s => { + return vectors + .map(v => { + return makeScalarVectorBinaryToVectorCase(s, v, op, quantize, scalarize); + }) + .filter(notUndefined); }); - return cases; } /** @@ -90,12 +92,12 @@ function generateScalarVectorBinaryToVectorCases( * @param quantize function to quantize all values in vectors and scalars * @param scalarize function to convert numbers to Scalars */ -function makeVectorScalarBinaryToVectorCase( - vector: readonly number[], - scalar: number, - op: BinaryOp, - quantize: QuantizeFunc, - scalarize: ScalarBuilder +function makeVectorScalarBinaryToVectorCase( + vector: readonly T[], + scalar: T, + op: BinaryOp, + quantize: QuantizeFunc, + scalarize: ScalarBuilder ): Case | undefined { vector = vector.map(quantize); scalar = quantize(scalar); @@ -105,7 +107,7 @@ function makeVectorScalarBinaryToVectorCase( } return { input: [new Vector(vector.map(scalarize)), scalarize(scalar)], - expected: new Vector((result as readonly number[]).map(scalarize)), + expected: new Vector(result.filter(notUndefined).map(scalarize)), }; } @@ -117,23 +119,20 @@ function makeVectorScalarBinaryToVectorCase( * @param quantize function to quantize all values in vectors and scalars * @param scalarize function to convert numbers to Scalars */ -function generateVectorScalarBinaryToVectorCases( - vectors: ROArrayArray, - scalars: readonly number[], - op: BinaryOp, - quantize: QuantizeFunc, - scalarize: ScalarBuilder +function generateVectorScalarBinaryToVectorCases( + vectors: ROArrayArray, + scalars: readonly T[], + op: BinaryOp, + quantize: QuantizeFunc, + scalarize: ScalarBuilder ): Case[] { - const cases = new Array(); - scalars.forEach(s => { - vectors.forEach(v => { - const c = makeVectorScalarBinaryToVectorCase(v, s, op, quantize, scalarize); - if (c !== undefined) { - cases.push(c); - } - }); + return scalars.flatMap(s => { + return vectors + .map(v => { + return makeVectorScalarBinaryToVectorCase(v, s, op, quantize, scalarize); + }) + .filter(notUndefined); }); - return cases; } /** @@ -145,7 +144,7 @@ function generateVectorScalarBinaryToVectorCases( export function generateU32VectorBinaryToVectorCases( scalars: readonly number[], vectors: ROArrayArray, - op: BinaryOp + op: BinaryOp ): Case[] { return generateScalarVectorBinaryToVectorCases(scalars, vectors, op, quantizeToU32, u32); } @@ -159,7 +158,7 @@ export function generateU32VectorBinaryToVectorCases( export function generateVectorU32BinaryToVectorCases( vectors: ROArrayArray, scalars: readonly number[], - op: BinaryOp + op: BinaryOp ): Case[] { return generateVectorScalarBinaryToVectorCases(vectors, scalars, op, quantizeToU32, u32); } @@ -173,7 +172,7 @@ export function generateVectorU32BinaryToVectorCases( export function generateI32VectorBinaryToVectorCases( scalars: readonly number[], vectors: ROArrayArray, - op: BinaryOp + op: BinaryOp ): Case[] { return generateScalarVectorBinaryToVectorCases(scalars, vectors, op, quantizeToI32, i32); } @@ -187,11 +186,39 @@ export function generateI32VectorBinaryToVectorCases( export function generateVectorI32BinaryToVectorCases( vectors: ROArrayArray, scalars: readonly number[], - op: BinaryOp + op: BinaryOp ): Case[] { return generateVectorScalarBinaryToVectorCases(vectors, scalars, op, quantizeToI32, i32); } +/** + * @returns array of Case for the input params with op applied + * @param scalars array of scalar params + * @param vectors array of vector params (2, 3, or 4 elements) + * @param op he op to apply to each pair of scalar and vector + */ +export function generateI64VectorBinaryToVectorCases( + scalars: readonly bigint[], + vectors: ROArrayArray, + op: BinaryOp +): Case[] { + return generateScalarVectorBinaryToVectorCases(scalars, vectors, op, quantizeToI64, abstractInt); +} + +/** + * @returns array of Case for the input params with op applied + * @param vectors array of vector params (2, 3, or 4 elements) + * @param scalars array of scalar params + * @param op he op to apply to each pair of vector and scalar + */ +export function generateVectorI64BinaryToVectorCases( + vectors: ROArrayArray, + scalars: readonly bigint[], + op: BinaryOp +): Case[] { + return generateVectorScalarBinaryToVectorCases(vectors, scalars, op, quantizeToI64, abstractInt); +} + /** * @returns array of Case for the input params with op applied * @param param0s array of inputs to try for the first param @@ -200,12 +227,12 @@ export function generateVectorI32BinaryToVectorCases( * @param quantize function to quantize all values * @param scalarize function to convert numbers to Scalars */ -function generateScalarBinaryToScalarCases( - param0s: readonly number[], - param1s: readonly number[], - op: BinaryOp, - quantize: QuantizeFunc, - scalarize: ScalarBuilder +function generateScalarBinaryToScalarCases( + param0s: readonly T[], + param1s: readonly T[], + op: BinaryOp, + quantize: QuantizeFunc, + scalarize: ScalarBuilder ): Case[] { param0s = param0s.map(quantize); param1s = param1s.map(quantize); @@ -227,7 +254,7 @@ function generateScalarBinaryToScalarCases( export function generateBinaryToI32Cases( param0s: readonly number[], param1s: readonly number[], - op: BinaryOp + op: BinaryOp ) { return generateScalarBinaryToScalarCases(param0s, param1s, op, quantizeToI32, i32); } @@ -241,7 +268,21 @@ export function generateBinaryToI32Cases( export function generateBinaryToU32Cases( param0s: readonly number[], param1s: readonly number[], - op: BinaryOp + op: BinaryOp ) { return generateScalarBinaryToScalarCases(param0s, param1s, op, quantizeToU32, u32); } + +/** + * @returns an array of Cases for operations over a range of inputs + * @param param0s array of inputs to try for the first param + * @param param1s array of inputs to try for the second param + * @param op callback called on each pair of inputs to produce each case + */ +export function generateBinaryToI64Cases( + param0s: readonly bigint[], + param1s: readonly bigint[], + op: BinaryOp +) { + return generateScalarBinaryToScalarCases(param0s, param1s, op, quantizeToI64, abstractInt); +} diff --git a/src/webgpu/util/conversion.ts b/src/webgpu/util/conversion.ts index 91174df74b3d..2d6462451119 100644 --- a/src/webgpu/util/conversion.ts +++ b/src/webgpu/util/conversion.ts @@ -1032,8 +1032,8 @@ export class Scalar { } } -export interface ScalarBuilder { - (value: number): Scalar; +export interface ScalarBuilder { + (value: T): Scalar; } /** Create a Scalar of `type` by storing `value` as an element of `workingDataArray` and retrieving it. diff --git a/src/webgpu/util/math.ts b/src/webgpu/util/math.ts index 036552847f78..5b04bef963d7 100644 --- a/src/webgpu/util/math.ts +++ b/src/webgpu/util/math.ts @@ -1293,6 +1293,67 @@ export function fullU32Range(count: number = 50): Array { return [0, ...biasedRange(1, kValue.u32.max, count)].map(Math.trunc); } +/** Short list of i64 values of interest to test against */ +const kInterestingI64Values: readonly bigint[] = [ + kValue.i64.negative.max, + kValue.i64.negative.max / 2n, + -256n, + -10n, + -1n, + 0n, + 1n, + 10n, + 256n, + kValue.i64.positive.max / 2n, + kValue.i64.positive.max, +]; + +/** @returns minimal i64 values that cover the entire range of i64 behaviours + * + * This is used instead of fullI64Range when the number of test cases being + * generated is a super linear function of the length of i64 values which is + * leading to time outs. + */ +export function sparseI64Range(): readonly bigint[] { + return kInterestingI64Values; +} + +const kVectorI64Values = { + 2: kInterestingI64Values.flatMap(f => [ + [f, 1n], + [-1n, f], + ]), + 3: kInterestingI64Values.flatMap(f => [ + [f, 1n, -2n], + [-1n, f, 2n], + [1n, -2n, f], + ]), + 4: kInterestingI64Values.flatMap(f => [ + [f, -1n, 2n, 3n], + [1n, f, -2n, 3n], + [1n, 2n, f, -3n], + [-1n, 2n, -3n, f], + ]), +}; + +/** + * Returns set of vectors, indexed by dimension containing interesting i64 + * values. + * + * The tests do not do the simple option for coverage of computing the cartesian + * product of all of the interesting i64 values N times for vecN tests, + * because that creates a huge number of tests for vec3 and vec4, leading to + * time outs. + * + * Instead they insert the interesting i64 values into each location of the + * vector to get a spread of testing over the entire range. This reduces the + * number of cases being run substantially, but maintains coverage. + */ +export function vectorI64Range(dim: number): ROArrayArray { + assert(dim === 2 || dim === 3 || dim === 4, 'vectorI64Range only accepts dimensions 2, 3, and 4'); + return kVectorI64Values[dim]; +} + /** * @returns an ascending sorted array of numbers spread over the entire range of 64-bit signed ints * @@ -2030,8 +2091,8 @@ export function signExtend(n: number, bits: number): number { return (n << shift) >> shift; } -export interface QuantizeFunc { - (num: number): number; +export interface QuantizeFunc { + (num: T): T; } /** @returns the closest 32-bit floating point value to the input */ @@ -2072,6 +2133,19 @@ export function quantizeToU32(num: number): number { return Math.trunc(num); } +/** + * @returns the closest 64-bit signed integer value to the input. + */ +export function quantizeToI64(num: bigint): bigint { + if (num >= kValue.i64.positive.max) { + return kValue.i64.positive.max; + } + if (num <= kValue.i64.negative.min) { + return kValue.i64.negative.min; + } + return num; +} + /** @returns whether the number is an integer and a power of two */ export function isPowerOfTwo(n: number): boolean { if (!Number.isInteger(n)) {