diff --git a/src/resources/cache/hashes.json b/src/resources/cache/hashes.json index dfb6d933dce5..c28e6a22e429 100644 --- a/src/resources/cache/hashes.json +++ b/src/resources/cache/hashes.json @@ -1,110 +1,110 @@ { - "webgpu/shader/execution/binary/af_addition.bin": "3537bbf", - "webgpu/shader/execution/binary/af_logical.bin": "a483b968", - "webgpu/shader/execution/binary/af_division.bin": "8759f887", - "webgpu/shader/execution/binary/af_matrix_addition.bin": "3eb7b746", - "webgpu/shader/execution/binary/af_matrix_subtraction.bin": "a1173db6", - "webgpu/shader/execution/binary/af_multiplication.bin": "b77f680a", - "webgpu/shader/execution/binary/af_remainder.bin": "c4697dfb", - "webgpu/shader/execution/binary/af_subtraction.bin": "17624e58", - "webgpu/shader/execution/binary/f16_addition.bin": "32b920a0", - "webgpu/shader/execution/binary/f16_logical.bin": "b89ca9b9", - "webgpu/shader/execution/binary/f16_division.bin": "e1e74564", - "webgpu/shader/execution/binary/f16_matrix_addition.bin": "37418ae2", - "webgpu/shader/execution/binary/f16_matrix_matrix_multiplication.bin": "f9e16ada", - "webgpu/shader/execution/binary/f16_matrix_scalar_multiplication.bin": "739ecb65", - "webgpu/shader/execution/binary/f16_matrix_subtraction.bin": "c20eaf83", - "webgpu/shader/execution/binary/f16_matrix_vector_multiplication.bin": "1e0127c0", - "webgpu/shader/execution/binary/f16_multiplication.bin": "e89c81f8", - "webgpu/shader/execution/binary/f16_remainder.bin": "85339fca", - "webgpu/shader/execution/binary/f16_subtraction.bin": "cd4bf3d3", - "webgpu/shader/execution/binary/f32_addition.bin": "9eaa0e04", - "webgpu/shader/execution/binary/f32_logical.bin": "c7370c09", - "webgpu/shader/execution/binary/f32_division.bin": "a81fa2e1", - "webgpu/shader/execution/binary/f32_matrix_addition.bin": "e3a3f2a2", - "webgpu/shader/execution/binary/f32_matrix_matrix_multiplication.bin": "51146714", - "webgpu/shader/execution/binary/f32_matrix_scalar_multiplication.bin": "99d99f13", - "webgpu/shader/execution/binary/f32_matrix_subtraction.bin": "dfab64d5", - "webgpu/shader/execution/binary/f32_matrix_vector_multiplication.bin": "f7de887d", - "webgpu/shader/execution/binary/f32_multiplication.bin": "ec380a2f", - "webgpu/shader/execution/binary/f32_remainder.bin": "8113a345", - "webgpu/shader/execution/binary/f32_subtraction.bin": "c65c7882", - "webgpu/shader/execution/binary/i32_arithmetic.bin": "a0b0a016", - "webgpu/shader/execution/binary/i32_comparison.bin": "f3d9b3f9", - "webgpu/shader/execution/binary/u32_arithmetic.bin": "16e32fd", - "webgpu/shader/execution/binary/u32_comparison.bin": "da33cc5d", - "webgpu/shader/execution/abs.bin": "e7d0db43", - "webgpu/shader/execution/acos.bin": "5c26b875", - "webgpu/shader/execution/acosh.bin": "6006745a", - "webgpu/shader/execution/asin.bin": "bd0a6605", - "webgpu/shader/execution/asinh.bin": "871eabc6", - "webgpu/shader/execution/atan.bin": "87e5508e", - "webgpu/shader/execution/atan2.bin": "587e430f", - "webgpu/shader/execution/atanh.bin": "24973287", - "webgpu/shader/execution/bitcast.bin": "d3767f75", - "webgpu/shader/execution/ceil.bin": "3597359f", - "webgpu/shader/execution/clamp.bin": "db80e3d4", - "webgpu/shader/execution/cos.bin": "be6a43df", - "webgpu/shader/execution/cosh.bin": "6b1522b4", - "webgpu/shader/execution/cross.bin": "6e12c696", - "webgpu/shader/execution/degrees.bin": "272d85f9", - "webgpu/shader/execution/determinant.bin": "e8c0910f", - "webgpu/shader/execution/distance.bin": "fcd1a459", - "webgpu/shader/execution/dot.bin": "6cb8305e", - "webgpu/shader/execution/exp.bin": "340a4471", - "webgpu/shader/execution/exp2.bin": "c3483a4f", - "webgpu/shader/execution/faceForward.bin": "2d7047cb", - "webgpu/shader/execution/floor.bin": "64eb44f3", - "webgpu/shader/execution/fma.bin": "af8fc9a1", - "webgpu/shader/execution/fract.bin": "546bfc4b", - "webgpu/shader/execution/frexp.bin": "73131e48", - "webgpu/shader/execution/inverseSqrt.bin": "af8b8480", - "webgpu/shader/execution/ldexp.bin": "b5d05356", - "webgpu/shader/execution/length.bin": "87a7a79e", - "webgpu/shader/execution/log.bin": "d7929d6d", - "webgpu/shader/execution/log2.bin": "4ba66d33", - "webgpu/shader/execution/max.bin": "ebc85f1f", - "webgpu/shader/execution/min.bin": "5b60cb58", - "webgpu/shader/execution/mix.bin": "c8ec2505", - "webgpu/shader/execution/modf.bin": "de35d27c", - "webgpu/shader/execution/normalize.bin": "1824edd9", - "webgpu/shader/execution/pack2x16float.bin": "e6859c1a", - "webgpu/shader/execution/pow.bin": "6b8532ae", - "webgpu/shader/execution/quantizeToF16.bin": "4956513f", - "webgpu/shader/execution/radians.bin": "199010e", - "webgpu/shader/execution/reflect.bin": "995fae9e", - "webgpu/shader/execution/refract.bin": "181fbbc8", - "webgpu/shader/execution/round.bin": "98dce70b", - "webgpu/shader/execution/saturate.bin": "3060e843", - "webgpu/shader/execution/sign.bin": "7879f29c", - "webgpu/shader/execution/sin.bin": "1f3d20e3", - "webgpu/shader/execution/sinh.bin": "749425d6", - "webgpu/shader/execution/smoothstep.bin": "3b82bce3", - "webgpu/shader/execution/sqrt.bin": "b2e5210a", - "webgpu/shader/execution/step.bin": "7d27ada6", - "webgpu/shader/execution/tan.bin": "a9edf243", - "webgpu/shader/execution/tanh.bin": "a733eb02", - "webgpu/shader/execution/transpose.bin": "f1a8852b", - "webgpu/shader/execution/trunc.bin": "3a3cf31f", - "webgpu/shader/execution/unpack2x16float.bin": "e3450db3", - "webgpu/shader/execution/unpack2x16snorm.bin": "beb21243", - "webgpu/shader/execution/unpack2x16unorm.bin": "37aab928", - "webgpu/shader/execution/unpack4x8snorm.bin": "1b57ee27", - "webgpu/shader/execution/unpack4x8unorm.bin": "19b3ac32", - "webgpu/shader/execution/unary/af_arithmetic.bin": "113dbf1a", - "webgpu/shader/execution/unary/af_assignment.bin": "47945f59", + "webgpu/shader/execution/binary/af_addition.bin": "ef1b2a5a", + "webgpu/shader/execution/binary/af_logical.bin": "2f3b0449", + "webgpu/shader/execution/binary/af_division.bin": "91f6a50e", + "webgpu/shader/execution/binary/af_matrix_addition.bin": "68f06b6d", + "webgpu/shader/execution/binary/af_matrix_subtraction.bin": "a29b1b2a", + "webgpu/shader/execution/binary/af_multiplication.bin": "5b249b97", + "webgpu/shader/execution/binary/af_remainder.bin": "c746b1c6", + "webgpu/shader/execution/binary/af_subtraction.bin": "c4f02864", + "webgpu/shader/execution/binary/f16_addition.bin": "deaa570d", + "webgpu/shader/execution/binary/f16_logical.bin": "bdeecd90", + "webgpu/shader/execution/binary/f16_division.bin": "ad886bb9", + "webgpu/shader/execution/binary/f16_matrix_addition.bin": "e3e830b4", + "webgpu/shader/execution/binary/f16_matrix_matrix_multiplication.bin": "1efcd108", + "webgpu/shader/execution/binary/f16_matrix_scalar_multiplication.bin": "6e681e70", + "webgpu/shader/execution/binary/f16_matrix_subtraction.bin": "e1be7c7f", + "webgpu/shader/execution/binary/f16_matrix_vector_multiplication.bin": "fbf28fa0", + "webgpu/shader/execution/binary/f16_multiplication.bin": "89d45ebd", + "webgpu/shader/execution/binary/f16_remainder.bin": "d31a6d89", + "webgpu/shader/execution/binary/f16_subtraction.bin": "bce603a2", + "webgpu/shader/execution/binary/f32_addition.bin": "316d2809", + "webgpu/shader/execution/binary/f32_logical.bin": "ef594391", + "webgpu/shader/execution/binary/f32_division.bin": "b687682c", + "webgpu/shader/execution/binary/f32_matrix_addition.bin": "6618fb53", + "webgpu/shader/execution/binary/f32_matrix_matrix_multiplication.bin": "43239b66", + "webgpu/shader/execution/binary/f32_matrix_scalar_multiplication.bin": "9ae2bcf8", + "webgpu/shader/execution/binary/f32_matrix_subtraction.bin": "9725b06c", + "webgpu/shader/execution/binary/f32_matrix_vector_multiplication.bin": "b3bd584e", + "webgpu/shader/execution/binary/f32_multiplication.bin": "801d9d66", + "webgpu/shader/execution/binary/f32_remainder.bin": "ece8752c", + "webgpu/shader/execution/binary/f32_subtraction.bin": "bd1f20dd", + "webgpu/shader/execution/binary/i32_arithmetic.bin": "a8e31d1d", + "webgpu/shader/execution/binary/i32_comparison.bin": "cb513412", + "webgpu/shader/execution/binary/u32_arithmetic.bin": "3a4e8b28", + "webgpu/shader/execution/binary/u32_comparison.bin": "f4faed06", + "webgpu/shader/execution/abs.bin": "c56243f5", + "webgpu/shader/execution/acos.bin": "d671944f", + "webgpu/shader/execution/acosh.bin": "aef9992d", + "webgpu/shader/execution/asin.bin": "a3c6f5df", + "webgpu/shader/execution/asinh.bin": "be442250", + "webgpu/shader/execution/atan.bin": "deefe71", + "webgpu/shader/execution/atan2.bin": "81217b83", + "webgpu/shader/execution/atanh.bin": "6843748a", + "webgpu/shader/execution/bitcast.bin": "344cc17a", + "webgpu/shader/execution/ceil.bin": "a4d239a0", + "webgpu/shader/execution/clamp.bin": "1e63217d", + "webgpu/shader/execution/cos.bin": "e6c1fdc4", + "webgpu/shader/execution/cosh.bin": "cdd1f595", + "webgpu/shader/execution/cross.bin": "adb0bbf5", + "webgpu/shader/execution/degrees.bin": "b594d698", + "webgpu/shader/execution/determinant.bin": "73407c59", + "webgpu/shader/execution/distance.bin": "2e1c9ab4", + "webgpu/shader/execution/dot.bin": "1028309a", + "webgpu/shader/execution/exp.bin": "1bc92f9a", + "webgpu/shader/execution/exp2.bin": "836a1e66", + "webgpu/shader/execution/faceForward.bin": "366e24b3", + "webgpu/shader/execution/floor.bin": "91015364", + "webgpu/shader/execution/fma.bin": "a6c54ea7", + "webgpu/shader/execution/fract.bin": "5fc52848", + "webgpu/shader/execution/frexp.bin": "51292173", + "webgpu/shader/execution/inverseSqrt.bin": "b9b0ae99", + "webgpu/shader/execution/ldexp.bin": "ea263df5", + "webgpu/shader/execution/length.bin": "7976e258", + "webgpu/shader/execution/log.bin": "9d5760d3", + "webgpu/shader/execution/log2.bin": "a25cf8fb", + "webgpu/shader/execution/max.bin": "ae846d", + "webgpu/shader/execution/min.bin": "8d5bf419", + "webgpu/shader/execution/mix.bin": "ec9b70a5", + "webgpu/shader/execution/modf.bin": "e715d023", + "webgpu/shader/execution/normalize.bin": "fd2b0e38", + "webgpu/shader/execution/pack2x16float.bin": "9f7090b0", + "webgpu/shader/execution/pow.bin": "8ef53194", + "webgpu/shader/execution/quantizeToF16.bin": "898deab3", + "webgpu/shader/execution/radians.bin": "402b8cfc", + "webgpu/shader/execution/reflect.bin": "dd6092d2", + "webgpu/shader/execution/refract.bin": "fcb87a99", + "webgpu/shader/execution/round.bin": "784dff70", + "webgpu/shader/execution/saturate.bin": "5b1a465", + "webgpu/shader/execution/sign.bin": "15e32305", + "webgpu/shader/execution/sin.bin": "7d9f3bf6", + "webgpu/shader/execution/sinh.bin": "74c0da74", + "webgpu/shader/execution/smoothstep.bin": "8934b7cf", + "webgpu/shader/execution/sqrt.bin": "fca89209", + "webgpu/shader/execution/step.bin": "71afbcf9", + "webgpu/shader/execution/tan.bin": "ea17d347", + "webgpu/shader/execution/tanh.bin": "c63e2ccf", + "webgpu/shader/execution/transpose.bin": "320af848", + "webgpu/shader/execution/trunc.bin": "5d2eced1", + "webgpu/shader/execution/unpack2x16float.bin": "d8e95aa8", + "webgpu/shader/execution/unpack2x16snorm.bin": "c09c4961", + "webgpu/shader/execution/unpack2x16unorm.bin": "fb72f053", + "webgpu/shader/execution/unpack4x8snorm.bin": "2b203d72", + "webgpu/shader/execution/unpack4x8unorm.bin": "1908b0bc", + "webgpu/shader/execution/unary/af_arithmetic.bin": "4fb1cabc", + "webgpu/shader/execution/unary/af_assignment.bin": "a6c21fc6", "webgpu/shader/execution/unary/bool_conversion.bin": "dd71f171", - "webgpu/shader/execution/unary/f16_arithmetic.bin": "1d6b84ef", - "webgpu/shader/execution/unary/f16_conversion.bin": "406aff92", - "webgpu/shader/execution/unary/f32_arithmetic.bin": "6d2c7f7b", - "webgpu/shader/execution/unary/f32_conversion.bin": "d7f9967f", + "webgpu/shader/execution/unary/f16_arithmetic.bin": "c2e491ce", + "webgpu/shader/execution/unary/f16_conversion.bin": "4da55ca6", + "webgpu/shader/execution/unary/f32_arithmetic.bin": "b4b7823e", + "webgpu/shader/execution/unary/f32_conversion.bin": "1285037c", "webgpu/shader/execution/unary/i32_arithmetic.bin": "c69716e2", "webgpu/shader/execution/unary/i32_conversion.bin": "83218e69", "webgpu/shader/execution/unary/u32_conversion.bin": "8f5bad00", "webgpu/shader/execution/unary/ai_assignment.bin": "c7e6ac33", - "webgpu/shader/execution/binary/ai_arithmetic.bin": "81c11ec2", + "webgpu/shader/execution/binary/ai_arithmetic.bin": "fe312677", "webgpu/shader/execution/unary/ai_arithmetic.bin": "3d27dc97", - "webgpu/shader/execution/binary/af_matrix_matrix_multiplication.bin": "df23d63a", - "webgpu/shader/execution/binary/af_matrix_scalar_multiplication.bin": "718ef50", - "webgpu/shader/execution/binary/af_matrix_vector_multiplication.bin": "495e66cf" + "webgpu/shader/execution/binary/af_matrix_matrix_multiplication.bin": "e0d69ae6", + "webgpu/shader/execution/binary/af_matrix_scalar_multiplication.bin": "5347f7ef", + "webgpu/shader/execution/binary/af_matrix_vector_multiplication.bin": "79a9997" } \ No newline at end of file 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 907c1b3caa69..aab59b667668 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_scalar_multiplication.bin b/src/resources/cache/webgpu/shader/execution/binary/af_matrix_scalar_multiplication.bin index 0d36869d6122..7bf6a775bd57 100644 Binary files a/src/resources/cache/webgpu/shader/execution/binary/af_matrix_scalar_multiplication.bin and b/src/resources/cache/webgpu/shader/execution/binary/af_matrix_scalar_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 5485a64411d2..2850d4577b69 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/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 e719ab3a00f4..abc392959182 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 @@ -1,16 +1,16 @@ import { FP } from '../../../../util/floating_point.js'; import { sparseMatrixF64Range } from '../../../../util/math.js'; -import { StochasticFilter } from '../../../../util/stochastic_filter.js'; +import { selectNCases } from '../case.js'; import { makeCaseCache } from '../case_cache.js'; -const sf = new StochasticFilter(0); // Cases: matKxR_matCxK const mat_mat_cases = ([2, 3, 4] as const) .flatMap(k => ([2, 3, 4] as const).flatMap(cols => ([2, 3, 4] as const).map(rows => ({ [`mat${k}x${rows}_mat${cols}x${k}`]: () => { - return sf.filter( + return selectNCases( + 50, FP.abstract.generateMatrixPairToMatrixCases( sparseMatrixF64Range(k, rows), sparseMatrixF64Range(cols, k), diff --git a/src/webgpu/shader/execution/expression/binary/af_matrix_scalar_multiplication.cache.ts b/src/webgpu/shader/execution/expression/binary/af_matrix_scalar_multiplication.cache.ts index 89312b5a51cb..fb491f8ec056 100644 --- a/src/webgpu/shader/execution/expression/binary/af_matrix_scalar_multiplication.cache.ts +++ b/src/webgpu/shader/execution/expression/binary/af_matrix_scalar_multiplication.cache.ts @@ -1,5 +1,6 @@ import { FP } from '../../../../util/floating_point.js'; import { sparseMatrixF64Range, sparseScalarF64Range } from '../../../../util/math.js'; +import { selectNCases } from '../case.js'; import { makeCaseCache } from '../case_cache.js'; // Cases: matCxR_scalar @@ -7,11 +8,14 @@ const mat_scalar_cases = ([2, 3, 4] as const) .flatMap(cols => ([2, 3, 4] as const).map(rows => ({ [`mat${cols}x${rows}_scalar`]: () => { - return FP.abstract.generateMatrixScalarToMatrixCases( - sparseMatrixF64Range(cols, rows), - sparseScalarF64Range(), - 'finite', - FP.abstract.multiplicationMatrixScalarInterval + return selectNCases( + 50, + FP.abstract.generateMatrixScalarToMatrixCases( + sparseMatrixF64Range(cols, rows), + sparseScalarF64Range(), + 'finite', + FP.abstract.multiplicationMatrixScalarInterval + ) ); }, })) @@ -23,11 +27,14 @@ const scalar_mat_cases = ([2, 3, 4] as const) .flatMap(cols => ([2, 3, 4] as const).map(rows => ({ [`scalar_mat${cols}x${rows}`]: () => { - return FP.abstract.generateScalarMatrixToMatrixCases( - sparseScalarF64Range(), - sparseMatrixF64Range(cols, rows), - 'finite', - FP.abstract.multiplicationScalarMatrixInterval + return selectNCases( + 50, + FP.abstract.generateScalarMatrixToMatrixCases( + sparseScalarF64Range(), + sparseMatrixF64Range(cols, rows), + 'finite', + FP.abstract.multiplicationScalarMatrixInterval + ) ); }, })) 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 34d832d2f23e..1e2520c468a5 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 @@ -1,5 +1,6 @@ import { FP } from '../../../../util/floating_point.js'; import { sparseMatrixF64Range, sparseVectorF64Range } from '../../../../util/math.js'; +import { selectNCases } from '../case.js'; import { makeCaseCache } from '../case_cache.js'; // Cases: matCxR_vecC @@ -7,11 +8,14 @@ const mat_vec_cases = ([2, 3, 4] as const) .flatMap(cols => ([2, 3, 4] as const).map(rows => ({ [`mat${cols}x${rows}_vec${cols}`]: () => { - return FP.abstract.generateMatrixVectorToVectorCases( - sparseMatrixF64Range(cols, rows), - sparseVectorF64Range(cols), - 'finite', - FP.abstract.multiplicationMatrixVectorInterval + return selectNCases( + 50, + FP.abstract.generateMatrixVectorToVectorCases( + sparseMatrixF64Range(cols, rows), + sparseVectorF64Range(cols), + 'finite', + FP.abstract.multiplicationMatrixVectorInterval + ) ); }, })) @@ -23,11 +27,14 @@ const vec_mat_cases = ([2, 3, 4] as const) .flatMap(rows => ([2, 3, 4] as const).map(cols => ({ [`vec${rows}_mat${cols}x${rows}`]: () => { - return FP.abstract.generateVectorMatrixToVectorCases( - sparseVectorF64Range(rows), - sparseMatrixF64Range(cols, rows), - 'finite', - FP.abstract.multiplicationVectorMatrixInterval + return selectNCases( + 50, + FP.abstract.generateVectorMatrixToVectorCases( + sparseVectorF64Range(rows), + sparseMatrixF64Range(cols, rows), + 'finite', + FP.abstract.multiplicationVectorMatrixInterval + ) ); }, })) diff --git a/src/webgpu/shader/execution/expression/case.ts b/src/webgpu/shader/execution/expression/case.ts index 1cbde7be754f..55eaee02a41f 100644 --- a/src/webgpu/shader/execution/expression/case.ts +++ b/src/webgpu/shader/execution/expression/case.ts @@ -1,11 +1,13 @@ +import { crc32 } from '../../../../common/util/crc32.js'; import { ROArrayArray } from '../../../../common/util/types.js'; -import { ScalarBuilder, Value, Vector, i32, u32, abstractInt } from '../../../util/conversion.js'; +import { assert } from '../../../../common/util/util.js'; +import { abstractInt, i32, ScalarBuilder, u32, Value, Vector } from '../../../util/conversion.js'; import { - QuantizeFunc, cartesianProduct, + QuantizeFunc, quantizeToI32, - quantizeToU32, quantizeToI64, + quantizeToU32, } from '../../../util/math.js'; import { Expectation } from './expectation.js'; @@ -25,6 +27,41 @@ export type Case = { /** CaseList is a list of Cases */ export type CaseList = Array; +/** + * Filters a given set of Cases down to a target number of cases by + * randomly selecting which Cases to return. + * + * The selection algorithm is deterministic and stable for a case's + * inputs. + * + * This means that if a specific case is selected is not affected by the + * presence of other cases in the list, so in theory it is possible to create a + * pathological set of cases such that all or not of the cases are selected + * in spite of the target number. + * + * This is a trade-off from guaranteeing stability of the selected cases over + * small changes, so the target number of cases is more of a suggestion. It is + * still guaranteed that if you set n0 < n1, then the invocation with n0 will + * return at most the number of cases that n1 does, it just isn't guaranteed to + * be less. + * + * @param n number of cases targeted be returned. Expected to be a positive + * integer. If equal or greater than the number of cases, then all the + * cases are returned. 0 is not allowed, since it is likely a + * programming error, because if the caller intentionally wants 0 + * items, they can just use []. + * @param cases list of Cases to be selected from. + */ +export function selectNCases(n: number, cases: CaseList): CaseList { + assert(n > 0 && Math.round(n) === n, `n ${n} is expected to be a positive integer`); + const count = cases.length; + if (n >= count) { + return cases; + } + + return cases.filter(c => n * (0xffff_ffff / count) > crc32(c.input.toString())); +} + /** * A function that performs a binary operation on x and y, and returns the * expected result. diff --git a/src/webgpu/util/stochastic_filter.ts b/src/webgpu/util/stochastic_filter.ts deleted file mode 100644 index c1f48b8f9719..000000000000 --- a/src/webgpu/util/stochastic_filter.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { assert } from '../../common/util/util.js'; - -import { PRNG } from './prng.js'; - -/** - * Used to remove entries from a list in a deterministic, but stochastic manner. - * Uses the pseudo-number random number generator from prng.ts for selection. - */ -export class StochasticFilter { - private readonly prng: PRNG; - private ratio: number; - - /** - * Constructor - * @param seed init value to pass down to PRNG - * @param ratio is a value between 0.0 and 1.0 indicating the number of - * entries that should be retained by the filter, 0.0 indicates - * none, 1.0 indicates all, defaults to 0.5. - * At least this many entries will be retained, but since arrays - * contain discrete number of entries, an extra element may need - * to be retained to guarantee this. - * For example given 5 entries and ratio 0.5, the result will - * have 3 elements so that 0.5 are retained. - */ - constructor(seed: number, ratio: number = 0.5) { - assert(ratio >= 0.0 && ratio <= 1.0, 'ratio needs to be in the range [0.0, 1.0]'); - this.prng = new PRNG(seed); - this.ratio = ratio; - } - - /** - * @returns a list of filtered elements, order of the elements is preserved. - * @param input is a list of elements to be filtered - * @param ratio is the number of elements to retain, defaults to this.ratio. - * The calculation for result length uses ceil, so if the input - * is 10 elements long and ratio is set to 0.49, 5 elements will - * be retained, because 10 * 0.49 = 4.9, which ceils to 5. - */ - public filter(input: readonly T[], ratio = this.ratio): T[] { - const target_length = Math.ceil(input.length * ratio); - if (target_length === 0) { - return []; - } - - if (target_length === input.length) { - return [...input]; - } - - return this.shuffle([...input.keys()]) // randomly shuffle list of 0 to input.length - 1 indices - .slice(0, target_length - 1) // Take the first target_length indices - .sort() // Get them back in order - .map(idx => input[idx]); // Copy out the retained indice elements from input - } - - /** - * @returns the input, but shuffled. - * Implements Fisher–Yates as described in AoCP. - */ - private shuffle(input: readonly T[]): T[] { - const result = [...input]; - let temp: T; - for (let i = result.length - 1; i > 0; i--) { - const j = Math.floor(this.prng.random() * (i + 1)); - temp = result[i]; - result[i] = result[j]; - result[j] = temp; - } - return result; - } -}