feat: CPU implementation of std.transpose#2737
Conversation
c52a42e to
53d569a
Compare
|
pkg.pr.new packages benchmark commit |
Bundle size comparison (
|
| 🟢 Decreased | ➖ Unchanged | 🔴 Increased (max 0.02%) | ❔ Unknown |
|---|---|---|---|
| 0 | 239 | 83 | 0 |
import { ... } in PR vs import * as ... in PR (is the library tree-Shakeable?):
| Test | tsdown |
|---|---|
| tgpu_init.ts | 258.91 kB ( |
| tgpu_initFromDevice.ts | 258.40 kB ( |
| tgpu_resolve.ts | 164.60 kB ( |
| tgpu_resolveWithContext.ts | 164.54 kB ( |
| tgpu_bindGroupLayout.ts | 68.97 kB ( |
| tgpu_mutableAccessor.ts | 65.97 kB ( |
| tgpu_accessor.ts | 65.96 kB ( |
| tgpu_privateVar.ts | 65.31 kB ( |
| tgpu_workgroupVar.ts | 65.30 kB ( |
| tgpu_const.ts | 64.55 kB ( |
| tgpu_fn.ts | 38.14 kB ( |
| tgpu_fragmentFn.ts | 38.14 kB ( |
| tgpu_vertexFn.ts | 37.96 kB ( |
| tgpu_computeFn.ts | 37.66 kB ( |
| tgpu_vertexLayout.ts | 26.79 kB ( |
| tgpu_comptime.ts | 14.48 kB ( |
| tgpu_unroll.ts | 1.66 kB ( |
| tgpu_slot.ts | 1.54 kB ( |
| tgpu_lazy.ts | 1.19 kB ( |
If you wish to run a comparison for other, slower bundlers, run the 'Tree-shake test' from the GitHub Actions menu.
Resolution Time Benchmark---
config:
themeVariables:
xyChart:
plotColorPalette: "#E63946, #3B82F6, #059669"
---
xychart
title "Random Branching (🔴 PR | 🔵 main | 🟢 release)"
x-axis "max depth" [1, 2, 3, 4, 5, 6, 7, 8]
y-axis "time (ms)"
line [0.88, 1.77, 4.00, 6.06, 6.72, 11.78, 21.16, 23.25]
line [0.93, 1.87, 4.32, 6.09, 7.03, 12.35, 21.96, 24.42]
line [0.91, 1.85, 3.80, 6.27, 7.28, 11.96, 21.44, 22.58]
---
config:
themeVariables:
xyChart:
plotColorPalette: "#E63946, #3B82F6, #059669"
---
xychart
title "Linear Recursion (🔴 PR | 🔵 main | 🟢 release)"
x-axis "max depth" [1, 2, 3, 4, 5, 6, 7, 8]
y-axis "time (ms)"
line [0.30, 0.46, 0.70, 0.83, 1.13, 1.18, 1.43, 1.48]
line [0.28, 0.51, 0.68, 0.82, 1.11, 1.21, 1.42, 1.52]
line [0.29, 0.51, 0.69, 0.83, 1.17, 1.26, 1.42, 1.55]
---
config:
themeVariables:
xyChart:
plotColorPalette: "#E63946, #3B82F6, #059669"
---
xychart
title "Full Tree (🔴 PR | 🔵 main | 🟢 release)"
x-axis "max depth" [1, 2, 3, 4, 5, 6, 7, 8]
y-axis "time (ms)"
line [0.73, 2.15, 4.16, 6.67, 11.81, 24.15, 51.52, 105.95]
line [0.83, 1.92, 3.35, 6.38, 12.42, 25.83, 54.02, 109.76]
line [0.79, 1.86, 3.65, 5.95, 12.19, 24.69, 52.84, 108.41]
|
53d569a to
fb18dab
Compare
There was a problem hiding this comment.
Pull request overview
Adds a CPU-side implementation for std.transpose so matrix transposition works in JS execution, while still generating a WGSL transpose(...) call when used in GPU-transpiled code.
Changes:
- Implemented
std.transposeCPU behavior format2x2f,mat3x3f, andmat4x4fviaWORKAROUND_getSchema(...). - Added unit tests covering JS transposition results for 2x2/3x3/4x4 matrices.
- Added a codegen test asserting WGSL output uses the builtin
transpose(...)call.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| packages/typegpu/src/std/numeric.ts | Implements CPU transpose for square float matrices and wires it into dualImpl while keeping WGSL codegen. |
| packages/typegpu/tests/std/transpose.test.ts | Adds coverage for CPU results and validates GPU codegen emits transpose(foo) in WGSL. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes — implemented the missing host-side CPU/JS std.transpose and added tests covering all currently supported square matrix sizes.
- Added
cpuTransposeinpackages/typegpu/src/std/numeric.tsto replace the placeholder error message. - Wired
unaryIdentitySignaturefor runtime/GPU type resolution, consistent with other unary builtins likeabs. - Added unit tests for
mat2x2f,mat3x3f, andmat4x4fhost transpositions plus atgpu.resolvesnapshot for the GPUtranspose()builtin path.
Kimi K2 (free via Pullfrog for OSS) | 𝕏
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes — incremental — added explicit toString(): string declarations to the matrix instance interfaces and removed the now-unnecessary typescript/no-base-to-string lint override in niceStringify. The original cpuTranspose implementation and tests remain unchanged.
packages/typegpu/src/data/wgslTypes.tsnow declarestoString(): stringonmat2x2,mat3x3, andmat4x4interfaces, matching the runtime method already provided by the concrete matrix classes.packages/typegpu/src/shared/stringify.tsdrops the oxlint disable comment because matrices are no longer treated as implicitly usingObject.prototype.toString.- Re-verified:
npx vitest run tests/std— 374 passed; oxlint on changed files — clean.
Kimi K2 (free via Pullfrog for OSS) | 𝕏
| }); | ||
|
|
||
| export const transpose = dualImpl<<T extends AnyMatInstance>(e: T) => T>({ | ||
| function cpuTranspose<T extends AnyMatInstance>(value: T): T { |
There was a problem hiding this comment.
I would hardcode it for every size in {2, 3, 4}, for example 2x2 transposition
const schema = WORKAROUND_getSchema(value);
const transposed = schema() as T;
const src = value.columns;
const dst = transposed.columns;
dst[0]![0] = src[0]![0]!;
dst[0]![1] = src[1]![0]!;
dst[1]![0] = src[0]![1]!;
dst[1]![1] = src[1]![1]!;
return transposed;There was a problem hiding this comment.
For the sake of performance?

In addition, the TS type system is now made aware that matrices have a custom
toStringmethod, so ignoring the lint rule is no longer necessary.