From dcec3009d288ffe2ee88e7d3841df2f3d9225b6f Mon Sep 17 00:00:00 2001 From: Aleksander Katan Date: Wed, 19 Nov 2025 18:13:11 +0100 Subject: [PATCH 1/8] Add some basic working vararg min --- packages/typegpu/src/std/numeric.ts | 45 ++++++++++++++----- .../typegpu/tests/std/numeric/min.test.ts | 42 +++++++++++++++++ 2 files changed, 77 insertions(+), 10 deletions(-) create mode 100644 packages/typegpu/tests/std/numeric/min.test.ts diff --git a/packages/typegpu/src/std/numeric.ts b/packages/typegpu/src/std/numeric.ts index de02cf4e7..bbfffe7d7 100644 --- a/packages/typegpu/src/std/numeric.ts +++ b/packages/typegpu/src/std/numeric.ts @@ -14,7 +14,7 @@ import { i32, u32, } from '../data/numeric.ts'; -import { snip } from '../data/snippet.ts'; +import { snip, Snippet } from '../data/snippet.ts'; import { abstruct } from '../data/struct.ts'; import { vec2f, @@ -56,6 +56,31 @@ import { mul, sub } from './operators.ts'; type NumVec = AnyNumericVecInstance; +const unaryIdentitySignature = (arg: AnyData) => { + return { + argTypes: [arg], + returnType: arg, + }; +}; + +function generalizeForVarArgs(fn: (a: T, b: T) => T) { + return (fst: T, ...rest: T[]): T => { + let acc = fst; + for (const r of rest) { + acc = fn(acc, r); + } + return acc; + }; +} + +function varArgsWrapStitch(wrapper: string, fst: Snippet, ...rest: Snippet[]) { + let acc = stitch`${fst}`; + for (const r of rest) { + acc = stitch`${wrapper}(${acc}, ${r})`; + } + return acc; +} + function cpuAbs(value: number): number; function cpuAbs(value: T): T; function cpuAbs(value: T): T { @@ -65,13 +90,6 @@ function cpuAbs(value: T): T { return VectorOps.abs[value.kind](value) as T; } -const unaryIdentitySignature = (arg: AnyData) => { - return { - argTypes: [arg], - returnType: arg, - }; -}; - export const abs = dualImpl({ name: 'abs', signature: unaryIdentitySignature, @@ -789,6 +807,12 @@ function cpuMin(a: T, b: T): T { return VectorOps.min[a.kind](a, b as NumVec) as T; } +type VarArgsOverload = { + (fst: number, ...rest: number[]): number; + (fst: T, ...rest: T[]): T; +}; +const cpuMinVarArgs = generalizeForVarArgs(cpuMin) as VarArgsOverload; + export const min = dualImpl({ name: 'min', signature: (...args) => { @@ -798,8 +822,9 @@ export const min = dualImpl({ returnType: uargs[0], }); }, - normalImpl: cpuMin, - codegenImpl: (a, b) => stitch`min(${a}, ${b})`, + normalImpl: cpuMinVarArgs, + codegenImpl: (...args): string => + varArgsWrapStitch('min', args[0], ...args.slice(1)), }); function cpuMix(e1: number, e2: number, e3: number): number; diff --git a/packages/typegpu/tests/std/numeric/min.test.ts b/packages/typegpu/tests/std/numeric/min.test.ts new file mode 100644 index 000000000..7e6e8aa8f --- /dev/null +++ b/packages/typegpu/tests/std/numeric/min.test.ts @@ -0,0 +1,42 @@ +import { describe, expect, it } from 'vitest'; +import { min } from '../../../src/std/index.ts'; +import tgpu from '../../../src/index.ts'; +import { f32, i32 } from '../../../src/data/numeric.ts'; + +describe('min', () => { + it('acts as identity when called with one argument', () => { + const myMin = (a: number) => { + 'use gpu'; + return min(a); + }; + + const main = () => { + 'use gpu'; + const x = myMin(2); + }; + + expect(tgpu.resolve([main])).toMatchInlineSnapshot(` + "fn myMin(a: i32) -> i32 { + return a; + } + + fn main() { + let x = myMin(2i); + }" + `); + }); + + it('works with multiple arguments', () => { + const myMin = tgpu.fn([f32, f32, f32, i32], f32)((a, b, c, d) => { + 'use gpu'; + return min(a, b, c, d, 7); + }); + + expect(myMin(2, 1, 4, 5)).toBe(1); + expect(tgpu.resolve([myMin])).toMatchInlineSnapshot(` + "fn myMin(a: f32, b: f32, c: f32, d: i32) -> f32 { + return min(min(min(min(a, b), c), f32(d)), 7f); + }" + `); + }); +}); From 560fa972154192746752941ea04746b93d1a6b57 Mon Sep 17 00:00:00 2001 From: Aleksander Katan Date: Thu, 20 Nov 2025 11:27:10 +0100 Subject: [PATCH 2/8] Add min tests --- .../typegpu/tests/std/numeric/min.test.ts | 83 ++++++++++++++----- 1 file changed, 63 insertions(+), 20 deletions(-) diff --git a/packages/typegpu/tests/std/numeric/min.test.ts b/packages/typegpu/tests/std/numeric/min.test.ts index 7e6e8aa8f..209c63468 100644 --- a/packages/typegpu/tests/std/numeric/min.test.ts +++ b/packages/typegpu/tests/std/numeric/min.test.ts @@ -1,41 +1,84 @@ import { describe, expect, it } from 'vitest'; -import { min } from '../../../src/std/index.ts'; import tgpu from '../../../src/index.ts'; -import { f32, i32 } from '../../../src/data/numeric.ts'; +import * as d from '../../../src/data/index.ts'; +import * as std from '../../../src/std/index.ts'; describe('min', () => { it('acts as identity when called with one argument', () => { - const myMin = (a: number) => { + const myMin = tgpu.fn([d.f32], d.f32)((a: number) => { 'use gpu'; - return min(a); - }; - - const main = () => { - 'use gpu'; - const x = myMin(2); - }; + return std.min(a); + }); - expect(tgpu.resolve([main])).toMatchInlineSnapshot(` - "fn myMin(a: i32) -> i32 { + expect(myMin(6)).toBe(6); + expect(tgpu.resolve([myMin])).toMatchInlineSnapshot(` + "fn myMin(a: f32) -> f32 { return a; - } + }" + `); + }); - fn main() { - let x = myMin(2i); + it('works with two arguments', () => { + const myMin = tgpu.fn([d.f32, d.f32], d.f32)((a, b) => { + 'use gpu'; + return std.min(a, b); + }); + + expect(myMin(1, 2)).toBe(1); + expect(tgpu.resolve([myMin])).toMatchInlineSnapshot(` + "fn myMin(a: f32, b: f32) -> f32 { + return min(a, b); }" `); }); it('works with multiple arguments', () => { - const myMin = tgpu.fn([f32, f32, f32, i32], f32)((a, b, c, d) => { + const myMin = tgpu.fn([d.f32, d.f32, d.f32, d.f32], d.f32)( + (a, b, c, d) => { + 'use gpu'; + return std.min(a, b, c, d); + }, + ); + + expect(myMin(2, 1, 4, 5)).toBe(1); + expect(tgpu.resolve([myMin])).toMatchInlineSnapshot(` + "fn myMin(a: f32, b: f32, c: f32, d2: f32) -> f32 { + return min(min(min(a, b), c), d2); + }" + `); + }); + + it('unifies arguments', () => { + const myMin = tgpu.fn([], d.f32)(() => { 'use gpu'; - return min(a, b, c, d, 7); + const a = d.u32(9); + const b = d.i32(1); + const c = d.f32(4); + return std.min(a, b, 3.3, c, 7); }); - expect(myMin(2, 1, 4, 5)).toBe(1); + expect(myMin()).toBe(1); + expect(tgpu.resolve([myMin])).toMatchInlineSnapshot(` + "fn myMin() -> f32 { + const a = 9u; + const b = 1i; + const c = 4f; + return min(min(min(min(f32(a), f32(b)), 3.3f), c), 7f); + }" + `); + }); + + it('works with vectors', () => { + const myMin = tgpu.fn([d.vec3u, d.vec3u], d.vec3u)((a, b) => { + 'use gpu'; + return std.min(a, b); + }); + + expect(myMin(d.vec3u(1, 2, 3), d.vec3u(3, 2, 1))) + .toStrictEqual(d.vec3u(1, 2, 1)); expect(tgpu.resolve([myMin])).toMatchInlineSnapshot(` - "fn myMin(a: f32, b: f32, c: f32, d: i32) -> f32 { - return min(min(min(min(a, b), c), f32(d)), 7f); + "fn myMin(a: vec3u, b: vec3u) -> vec3u { + return min(a, b); }" `); }); From 5612b16c76edb66b816ca05f6f459bef0d10793f Mon Sep 17 00:00:00 2001 From: Aleksander Katan Date: Thu, 20 Nov 2025 11:54:29 +0100 Subject: [PATCH 3/8] Refactor --- packages/typegpu/src/std/numeric.ts | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/packages/typegpu/src/std/numeric.ts b/packages/typegpu/src/std/numeric.ts index bbfffe7d7..98df1848b 100644 --- a/packages/typegpu/src/std/numeric.ts +++ b/packages/typegpu/src/std/numeric.ts @@ -56,6 +56,8 @@ import { mul, sub } from './operators.ts'; type NumVec = AnyNumericVecInstance; +// helpers + const unaryIdentitySignature = (arg: AnyData) => { return { argTypes: [arg], @@ -63,7 +65,9 @@ const unaryIdentitySignature = (arg: AnyData) => { }; }; -function generalizeForVarArgs(fn: (a: T, b: T) => T) { +// AAA signature for unify all + +function variadicReduce(fn: (a: T, b: T) => T) { return (fst: T, ...rest: T[]): T => { let acc = fst; for (const r of rest) { @@ -73,14 +77,16 @@ function generalizeForVarArgs(fn: (a: T, b: T) => T) { }; } -function varArgsWrapStitch(wrapper: string, fst: Snippet, ...rest: Snippet[]) { - let acc = stitch`${fst}`; +function variadicStitch(wrapper: string, ...rest: Snippet[]) { + let acc = ''; for (const r of rest) { acc = stitch`${wrapper}(${acc}, ${r})`; } return acc; } +// std + function cpuAbs(value: number): number; function cpuAbs(value: T): T; function cpuAbs(value: T): T { @@ -807,11 +813,10 @@ function cpuMin(a: T, b: T): T { return VectorOps.min[a.kind](a, b as NumVec) as T; } -type VarArgsOverload = { +type VariadicOverload = { (fst: number, ...rest: number[]): number; (fst: T, ...rest: T[]): T; }; -const cpuMinVarArgs = generalizeForVarArgs(cpuMin) as VarArgsOverload; export const min = dualImpl({ name: 'min', @@ -822,9 +827,8 @@ export const min = dualImpl({ returnType: uargs[0], }); }, - normalImpl: cpuMinVarArgs, - codegenImpl: (...args): string => - varArgsWrapStitch('min', args[0], ...args.slice(1)), + normalImpl: variadicReduce(cpuMin) as VariadicOverload, + codegenImpl: (...args): string => variadicStitch('min', ...args), }); function cpuMix(e1: number, e2: number, e3: number): number; From 48f112b6a1c0fdd1b11228054d71f636ba739348 Mon Sep 17 00:00:00 2001 From: Aleksander Katan Date: Thu, 20 Nov 2025 11:54:37 +0100 Subject: [PATCH 4/8] More tests --- .../typegpu/tests/std/numeric/max.test.ts | 94 +++++++++++++++++++ .../typegpu/tests/std/numeric/min.test.ts | 9 ++ 2 files changed, 103 insertions(+) create mode 100644 packages/typegpu/tests/std/numeric/max.test.ts diff --git a/packages/typegpu/tests/std/numeric/max.test.ts b/packages/typegpu/tests/std/numeric/max.test.ts new file mode 100644 index 000000000..f39f66729 --- /dev/null +++ b/packages/typegpu/tests/std/numeric/max.test.ts @@ -0,0 +1,94 @@ +import { describe, expect, it } from 'vitest'; +import tgpu from '../../../src/index.ts'; +import * as d from '../../../src/data/index.ts'; +import * as std from '../../../src/std/index.ts'; + +describe('max', () => { + it('acts as identity when called with one argument', () => { + const myMax = tgpu.fn([d.f32], d.f32)((a: number) => { + 'use gpu'; + return std.max(a); + }); + + expect(myMax(6)).toBe(6); + expect(tgpu.resolve([myMax])).toMatchInlineSnapshot(` + "fn myMax(a: f32) -> f32 { + return a; + }" + `); + }); + + it('works with two arguments', () => { + const myMax = tgpu.fn([d.f32, d.f32], d.f32)((a, b) => { + 'use gpu'; + return std.max(a, b); + }); + + expect(myMax(1, 2)).toBe(2); + expect(tgpu.resolve([myMax])).toMatchInlineSnapshot(` + "fn myMax(a: f32, b: f32) -> f32 { + return max(a, b); + }" + `); + }); + + it('works with multiple arguments', () => { + const myMax = tgpu.fn([d.f32, d.f32, d.f32, d.f32], d.f32)( + (a, b, c, d) => { + 'use gpu'; + return std.max(a, b, c, d); + }, + ); + + expect(myMax(2, 1, 4, 5)).toBe(5); + expect(tgpu.resolve([myMax])).toMatchInlineSnapshot(` + "fn myMax(a: f32, b: f32, c: f32, d2: f32) -> f32 { + return max(max(max(a, b), c), d2); + }" + `); + }); + + it('unifies arguments', () => { + const myMax = tgpu.fn([], d.f32)(() => { + 'use gpu'; + const a = d.u32(9); + const b = d.i32(1); + const c = d.f32(4); + return std.max(a, b, 3.3, c, 7); + }); + + expect(myMax()).toBe(9); + expect(tgpu.resolve([myMax])).toMatchInlineSnapshot(` + "fn myMax() -> f32 { + const a = 9u; + const b = 1i; + const c = 4f; + return max(max(max(max(f32(a), f32(b)), 3.3f), c), 7f); + }" + `); + }); + + it('works with vectors', () => { + const myMax = tgpu.fn([d.vec3u, d.vec3u], d.vec3u)((a, b) => { + 'use gpu'; + return std.max(a, b); + }); + + expect(myMax(d.vec3u(1, 2, 3), d.vec3u(3, 2, 1))) + .toStrictEqual(d.vec3u(3, 2, 3)); + expect(tgpu.resolve([myMax])).toMatchInlineSnapshot(` + "fn myMax(a: vec3u, b: vec3u) -> vec3u { + return max(a, b); + }" + `); + }); + + it('cannot be called with invalid arguments', () => { + // @ts-expect-error + (() => std.max()); + // @ts-expect-error + (() => std.max(1, d.vec2f())); + // @ts-expect-error + (() => std.max(d.vec3f(), d.vec2f())); + }); +}); diff --git a/packages/typegpu/tests/std/numeric/min.test.ts b/packages/typegpu/tests/std/numeric/min.test.ts index 209c63468..15248c375 100644 --- a/packages/typegpu/tests/std/numeric/min.test.ts +++ b/packages/typegpu/tests/std/numeric/min.test.ts @@ -82,4 +82,13 @@ describe('min', () => { }" `); }); + + it('cannot be called with invalid arguments', () => { + // @ts-expect-error + (() => std.min()); + // @ts-expect-error + (() => std.min(1, d.vec2f())); + // @ts-expect-error + (() => std.min(d.vec3f(), d.vec2f())); + }); }); From fc0f65237cef7ba1d87c0c9fdeee1d30568e688d Mon Sep 17 00:00:00 2001 From: Aleksander Katan Date: Thu, 20 Nov 2025 12:02:13 +0100 Subject: [PATCH 5/8] Update max --- packages/typegpu/src/std/numeric.ts | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/packages/typegpu/src/std/numeric.ts b/packages/typegpu/src/std/numeric.ts index 98df1848b..88745510d 100644 --- a/packages/typegpu/src/std/numeric.ts +++ b/packages/typegpu/src/std/numeric.ts @@ -66,6 +66,7 @@ const unaryIdentitySignature = (arg: AnyData) => { }; // AAA signature for unify all +// AAA use this min in examples function variadicReduce(fn: (a: T, b: T) => T) { return (fst: T, ...rest: T[]): T => { @@ -77,12 +78,14 @@ function variadicReduce(fn: (a: T, b: T) => T) { }; } -function variadicStitch(wrapper: string, ...rest: Snippet[]) { - let acc = ''; - for (const r of rest) { - acc = stitch`${wrapper}(${acc}, ${r})`; - } - return acc; +function variadicStitch(wrapper: string) { + return (fst: Snippet, ...rest: Snippet[]): string => { + let acc = stitch`${fst}`; + for (const r of rest) { + acc = stitch`${wrapper}(${acc}, ${r})`; + } + return acc; + }; } // std @@ -800,8 +803,8 @@ export const max = dualImpl({ returnType: uargs[0], }); }, - normalImpl: cpuMax, - codegenImpl: (a, b) => stitch`max(${a}, ${b})`, + normalImpl: variadicReduce(cpuMax) as VariadicOverload, + codegenImpl: variadicStitch('max'), }); function cpuMin(a: number, b: number): number; @@ -828,7 +831,7 @@ export const min = dualImpl({ }); }, normalImpl: variadicReduce(cpuMin) as VariadicOverload, - codegenImpl: (...args): string => variadicStitch('min', ...args), + codegenImpl: variadicStitch('min'), }); function cpuMix(e1: number, e2: number, e3: number): number; From a57b06912dd6e48be061f3be8c850286be5d5217 Mon Sep 17 00:00:00 2001 From: Aleksander Katan Date: Thu, 20 Nov 2025 12:08:14 +0100 Subject: [PATCH 6/8] Add `variadicUnifySignature` --- packages/typegpu/src/std/numeric.ts | 38 +++++++++-------------------- 1 file changed, 12 insertions(+), 26 deletions(-) diff --git a/packages/typegpu/src/std/numeric.ts b/packages/typegpu/src/std/numeric.ts index 88745510d..701a97cf3 100644 --- a/packages/typegpu/src/std/numeric.ts +++ b/packages/typegpu/src/std/numeric.ts @@ -65,7 +65,14 @@ const unaryIdentitySignature = (arg: AnyData) => { }; }; -// AAA signature for unify all +const variadicUnifySignature = (...args: AnyData[]) => { + const uargs = unify(args) ?? args; + return ({ + argTypes: uargs, + returnType: uargs[0] as AnyData, + }); +}; + // AAA use this min in examples function variadicReduce(fn: (a: T, b: T) => T) { @@ -258,10 +265,7 @@ function cpuClamp(value: T, low: T, high: T): T { export const clamp = dualImpl({ name: 'clamp', - signature: (...args) => { - const uargs = unify(args) ?? args; - return { argTypes: uargs, returnType: uargs[0] }; - }, + signature: variadicUnifySignature, normalImpl: cpuClamp, codegenImpl: (value, low, high) => stitch`clamp(${value}, ${low}, ${high})`, }); @@ -796,13 +800,7 @@ function cpuMax(a: T, b: T): T { export const max = dualImpl({ name: 'max', - signature: (...args) => { - const uargs = unify(args) ?? args; - return ({ - argTypes: uargs, - returnType: uargs[0], - }); - }, + signature: variadicUnifySignature, normalImpl: variadicReduce(cpuMax) as VariadicOverload, codegenImpl: variadicStitch('max'), }); @@ -823,13 +821,7 @@ type VariadicOverload = { export const min = dualImpl({ name: 'min', - signature: (...args) => { - const uargs = unify(args) ?? args; - return ({ - argTypes: uargs, - returnType: uargs[0], - }); - }, + signature: variadicUnifySignature, normalImpl: variadicReduce(cpuMin) as VariadicOverload, codegenImpl: variadicStitch('min'), }); @@ -860,13 +852,7 @@ function cpuMix( export const mix = dualImpl({ name: 'mix', - signature: (...args) => { - const uargs = unify(args) ?? args; - return ({ - argTypes: uargs, - returnType: uargs[0], - }); - }, + signature: variadicUnifySignature, normalImpl: cpuMix, codegenImpl: (e1, e2, e3) => stitch`mix(${e1}, ${e2}, ${e3})`, }); From 0abb7c67fbce761c40e565116bebfc5510301f2d Mon Sep 17 00:00:00 2001 From: Aleksander Katan Date: Thu, 20 Nov 2025 12:13:36 +0100 Subject: [PATCH 7/8] Use variadic min and max in examples --- .../src/content/docs/fundamentals/functions/index.mdx | 2 +- .../typegpu-docs/src/examples/rendering/jelly-slider/utils.ts | 4 ++-- .../typegpu-docs/src/examples/rendering/jelly-switch/utils.ts | 4 ++-- .../src/examples/simulation/slime-mold-3d/index.ts | 4 ++-- packages/typegpu/src/std/numeric.ts | 2 -- 5 files changed, 7 insertions(+), 9 deletions(-) diff --git a/apps/typegpu-docs/src/content/docs/fundamentals/functions/index.mdx b/apps/typegpu-docs/src/content/docs/fundamentals/functions/index.mdx index 3ed119308..a7c2c4fc2 100644 --- a/apps/typegpu-docs/src/content/docs/fundamentals/functions/index.mdx +++ b/apps/typegpu-docs/src/content/docs/fundamentals/functions/index.mdx @@ -323,7 +323,7 @@ function manhattanDistance(a: d.v3f, b: d.v3f) { const dy = std.abs(a.y - b.y); const dz = std.abs(a.z - b.z); - return std.max(dx, std.max(dy, dz)); + return std.max(dx, dy, dz); } ``` diff --git a/apps/typegpu-docs/src/examples/rendering/jelly-slider/utils.ts b/apps/typegpu-docs/src/examples/rendering/jelly-slider/utils.ts index d4b96cf9b..a3e3d0e22 100644 --- a/apps/typegpu-docs/src/examples/rendering/jelly-slider/utils.ts +++ b/apps/typegpu-docs/src/examples/rendering/jelly-slider/utils.ts @@ -33,8 +33,8 @@ export const intersectBox = ( const tMinVec = std.min(t1, t2); const tMaxVec = std.max(t1, t2); - const tMin = std.max(std.max(tMinVec.x, tMinVec.y), tMinVec.z); - const tMax = std.min(std.min(tMaxVec.x, tMaxVec.y), tMaxVec.z); + const tMin = std.max(tMinVec.x, tMinVec.y, tMinVec.z); + const tMax = std.min(tMaxVec.x, tMaxVec.y, tMaxVec.z); const result = BoxIntersection(); result.hit = tMax >= tMin && tMax >= 0.0; diff --git a/apps/typegpu-docs/src/examples/rendering/jelly-switch/utils.ts b/apps/typegpu-docs/src/examples/rendering/jelly-switch/utils.ts index c7277a7f3..ed5b0fa35 100644 --- a/apps/typegpu-docs/src/examples/rendering/jelly-switch/utils.ts +++ b/apps/typegpu-docs/src/examples/rendering/jelly-switch/utils.ts @@ -32,8 +32,8 @@ export const intersectBox = ( const tMinVec = std.min(t1, t2); const tMaxVec = std.max(t1, t2); - const tMin = std.max(std.max(tMinVec.x, tMinVec.y), tMinVec.z); - const tMax = std.min(std.min(tMaxVec.x, tMaxVec.y), tMaxVec.z); + const tMin = std.max(tMinVec.x, tMinVec.y, tMinVec.z); + const tMax = std.min(tMaxVec.x, tMaxVec.y, tMaxVec.z); const result = BoxIntersection(); result.hit = tMax >= tMin && tMax >= 0.0; diff --git a/apps/typegpu-docs/src/examples/simulation/slime-mold-3d/index.ts b/apps/typegpu-docs/src/examples/simulation/slime-mold-3d/index.ts index 2a6e2cc00..995c5461a 100644 --- a/apps/typegpu-docs/src/examples/simulation/slime-mold-3d/index.ts +++ b/apps/typegpu-docs/src/examples/simulation/slime-mold-3d/index.ts @@ -365,8 +365,8 @@ const rayBoxIntersection = ( const t1 = boxMax.sub(rayOrigin).mul(invDir); const tmin = std.min(t0, t1); const tmax = std.max(t0, t1); - const tNear = std.max(std.max(tmin.x, tmin.y), tmin.z); - const tFar = std.min(std.min(tmax.x, tmax.y), tmax.z); + const tNear = std.max(tmin.x, tmin.y, tmin.z); + const tFar = std.min(tmax.x, tmax.y, tmax.z); const hit = tFar >= tNear && tFar >= 0; return RayBoxResult({ tNear, tFar, hit }); }; diff --git a/packages/typegpu/src/std/numeric.ts b/packages/typegpu/src/std/numeric.ts index 701a97cf3..463de5d93 100644 --- a/packages/typegpu/src/std/numeric.ts +++ b/packages/typegpu/src/std/numeric.ts @@ -73,8 +73,6 @@ const variadicUnifySignature = (...args: AnyData[]) => { }); }; -// AAA use this min in examples - function variadicReduce(fn: (a: T, b: T) => T) { return (fst: T, ...rest: T[]): T => { let acc = fst; From b99196b93c31c8183087fa57f0f9196f1901cf51 Mon Sep 17 00:00:00 2001 From: Aleksander Katan Date: Thu, 20 Nov 2025 15:43:20 +0100 Subject: [PATCH 8/8] smol --- packages/typegpu/src/std/numeric.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/typegpu/src/std/numeric.ts b/packages/typegpu/src/std/numeric.ts index 463de5d93..17526c9af 100644 --- a/packages/typegpu/src/std/numeric.ts +++ b/packages/typegpu/src/std/numeric.ts @@ -796,6 +796,11 @@ function cpuMax(a: T, b: T): T { return VectorOps.max[a.kind](a, b as NumVec) as T; } +type VariadicOverload = { + (fst: number, ...rest: number[]): number; + (fst: T, ...rest: T[]): T; +}; + export const max = dualImpl({ name: 'max', signature: variadicUnifySignature, @@ -812,11 +817,6 @@ function cpuMin(a: T, b: T): T { return VectorOps.min[a.kind](a, b as NumVec) as T; } -type VariadicOverload = { - (fst: number, ...rest: number[]): number; - (fst: T, ...rest: T[]): T; -}; - export const min = dualImpl({ name: 'min', signature: variadicUnifySignature,