Skip to content

feat: d.arrayOf constant origin when all elements constant - #2872

Open
vende11s wants to merge 4 commits into
mainfrom
impr/inline-array-origin
Open

feat: d.arrayOf constant origin when all elements constant#2872
vende11s wants to merge 4 commits into
mainfrom
impr/inline-array-origin

Conversation

@vende11s

Copy link
Copy Markdown
Collaborator

No description provided.

Copilot AI lite review requested due to automatic review settings August 19, 2026 12:59

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Updates WGSL snippet origin tracking so arrays composed solely of constant values can be treated as constant, and extends test coverage to validate this behavior for array literals and d.arrayOf(...) instantiations.

Changes:

  • Propagate origin through d.arrayOf(...)([ ... ]) instantiation when the argument is an ArrayExpression.
  • Preserve constant-ness through array copies via fallthroughCopyOrigin(...).
  • Add tests asserting origin for captured array snippets is constant vs runtime based on element sources.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
packages/typegpu/tests/tgsl/wgslGenerator.test.ts Adds regression test coverage for constant-origin detection in array captures.
packages/typegpu/src/tgsl/wgslGenerator.ts Adjusts snippet origin inference/propagation for array literals and array instantiation/copies.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

return snip(
instantiated.value,
instantiated.dataType,
/* origin */ arg.origin,
Comment on lines +1002 to 1009
const allConstant = values.every((value) => value.origin === 'constant');

return snip(
new ArrayExpression(arrayType, values),
arrayType,
/* origin */ 'runtime',
/* origin */ allConstant ? 'constant' : 'runtime',
values.some((v) => v.possibleSideEffects),
);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wouldn't worry about this one too much

Comment thread packages/typegpu/src/tgsl/wgslGenerator.ts Outdated
Comment thread packages/typegpu/tests/tgsl/wgslGenerator.test.ts Outdated

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes — Reviewed PR #2872, which gives inline array literals ([...]) and d.arrayOf(...)([...]) a constant origin when every element is constant, so const-indexed accesses can emit WGSL const instead of let.

  • Constant origin for all-constant array literals (wgslGenerator.ts): the array-expression path now sets constant origin when every element resolves to constant, instead of hardcoding runtime — e.g. const v = array<u32, 4>(2u, 1u, 3u, 7u)[1i] is now emitted where it used to be a let.
  • Origin propagation through d.arrayOf(...)([...]) (wgslGenerator.ts): the instantiated array now inherits the argument array literal's origin, and the copy-from-value branch uses fallthroughCopyOrigin(arg.origin) (identical to the old runtime for every non-constant origin) instead of a hardcoded runtime.
  • Regression test (wgslGenerator.test.ts): a CAPTURE-based test covering plain literals, d.arrayOf over literals with mixed constant/runtime elements, and outer-const vs. inner-let capture.

I verified the mutation flow is unaffected (let a = [1, 2, 3]; a[0] = idx still emits var, since arrays are not naturally ephemeral and deferred variable types resolve off mutation tracking, not origin), confirmed the emitted const RHS is valid WGSL (spec §8.5.3 allows i32/u32 const indices), confirmed the new test genuinely fails when the fix is reverted, and ran the full typegpu public suite (175 files / 2346 tests) plus package typecheck and lint — all clean.

Pullfrog  | View workflow run | Using DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes — Reviewed the delta since the prior pullfrog review (commit c369a6a "apply review suggestions"), which restructures the test coverage added for constant array origins; the source hunks in wgslGenerator.ts are unchanged since the initial review (which was approved).

  • Split the single capture test into two (wgslGenerator.test.ts): separate array literals origin should be constant when all of its elements are constant and d.arrayOf origin should be constant when all of its elements are constant tests, in line with the reviewer's request.
  • Clarified the fixtures: each test now declares its own const x / let y and defines y before use inside the fn, making the constant-vs-runtime assertions self-contained and readable.

I verified the reworked tests are sound (values defined before use, assertions match the source all-constant logic) and ran tests/tgsl/wgslGenerator.test.ts — all 89 tests pass, including the two reworked cases.

Pullfrog  | View workflow run | Using DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes — Reviewed the delta since the prior pullfrog review (c369a6a "apply review suggestions"), namely commit 52f3f7a "fix typeInstantiation".

  • d.arrayOf(...)([...]) now uses the instantiated array's own origin (wgslGenerator.ts): the wrapped literal now passes instantiated.origin instead of arg.origin. Both derive from the same elements being constant, so this is behavior-preserving, but it no longer reaches into the argument's origin.
  • Composite constructors of all-constant args now yield constant (typeInstantiation, wgslGenerator.ts:1174-1179): the multi-arg return changed its origin from a hardcoded runtime to args.every((arg) => arg.origin === 'constant') ? 'constant' : 'runtime'. This is what lets non-array-literal constructor calls (e.g. d.arrayOf(u32, 4)([2, 1, 3, x]), vectors, matrices) become constant, keeping them consistent with the array-literal origin from the earlier commits.

I verified the origin computation is consistent (constant only when every argument is constant — the strict check means constant-immutable-def / runtime elements still fall through to runtime, conservatively), ran the full typegpu suite (175 files / 2347 tests, including the matrix/vector/struct constructors the broadened origin touches) and the package typecheck — all clean. No new issues.

Pullfrog  | View workflow run | Using DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

@iwoplaza iwoplaza changed the title Impr: d.arrayOf constant origin when all elements constant feat: d.arrayOf constant origin when all elements constant Aug 24, 2026
Comment thread packages/typegpu/src/tgsl/wgslGenerator.ts
Comment thread packages/typegpu/src/tgsl/wgslGenerator.ts
Comment thread packages/typegpu/src/tgsl/wgslGenerator.ts
@vende11s
vende11s force-pushed the impr/inline-array-origin branch from 52f3f7a to 0628976 Compare August 26, 2026 11:10
@github-actions

Copy link
Copy Markdown

pkg.pr.new

packages
Ready to be installed by your favorite package manager ⬇️

https://pkg.pr.new/software-mansion/TypeGPU/typegpu@0628976a5fecf457e2101380c598cf9766299a52

benchmark
view benchmark

commit
view commit

@github-actions

Copy link
Copy Markdown

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.81, 1.62, 3.59, 5.97, 7.51, 9.52, 21.52, 22.97]
  line [0.91, 1.75, 3.83, 6.16, 6.94, 9.70, 20.96, 20.61]
  line [0.91, 1.82, 3.90, 5.50, 6.42, 10.30, 19.74, 23.67]
Loading
---
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.32, 0.43, 0.59, 0.75, 1.00, 1.02, 1.18, 1.34]
  line [0.33, 0.52, 0.67, 0.76, 1.01, 1.12, 1.26, 1.40]
  line [0.27, 0.46, 0.60, 0.72, 1.06, 1.12, 1.32, 1.44]
Loading
---
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.76, 1.76, 3.06, 6.74, 10.69, 23.33, 49.31, 104.35]
  line [0.76, 1.96, 3.17, 6.15, 10.88, 23.04, 51.17, 104.31]
  line [0.81, 2.02, 3.03, 6.93, 11.04, 22.84, 50.66, 102.04]
Loading

@github-actions

Copy link
Copy Markdown

Bundle size comparison (import * as ... in PR vs import * as ... in target):

🟢 Decreased ➖ Unchanged 🔴 Increased (max 0.02%) ❔ Unknown
0 304 21 0

import { ... } in PR vs import * as ... in PR (is the library tree-Shakeable?):

Test tsdown
tgpu_init.ts 263.15 kB ($${\color{green}-3.5\%}$$)
tgpu_initFromDevice.ts 262.60 kB ($${\color{green}-3.7\%}$$)
tgpu_resolve.ts 161.79 kB ($${\color{green}-40.7\%}$$)
tgpu_resolveWithContext.ts 161.73 kB ($${\color{green}-40.7\%}$$)
tgpu_bindGroupLayout.ts 62.32 kB ($${\color{green}-77.1\%}$$)
tgpu_mutableAccessor.ts 57.04 kB ($${\color{green}-79.1\%}$$)
tgpu_accessor.ts 57.04 kB ($${\color{green}-79.1\%}$$)
tgpu_privateVar.ts 55.73 kB ($${\color{green}-79.6\%}$$)
tgpu_workgroupVar.ts 55.73 kB ($${\color{green}-79.6\%}$$)
tgpu_const.ts 55.15 kB ($${\color{green}-79.8\%}$$)
tgpu_lazy.ts 54.95 kB ($${\color{green}-79.8\%}$$)
tgpu_fragmentFn.ts 39.68 kB ($${\color{green}-85.4\%}$$)
tgpu_fn.ts 39.62 kB ($${\color{green}-85.5\%}$$)
tgpu_vertexFn.ts 39.50 kB ($${\color{green}-85.5\%}$$)
tgpu_computeFn.ts 39.20 kB ($${\color{green}-85.6\%}$$)
tgpu_vertexLayout.ts 28.33 kB ($${\color{green}-89.6\%}$$)
tgpu_comptime.ts 15.93 kB ($${\color{green}-94.2\%}$$)
tgpu_unroll.ts 1.75 kB ($${\color{green}-99.4\%}$$)
tgpu_slot.ts 1.70 kB ($${\color{green}-99.4\%}$$)

If you wish to run a comparison for other, slower bundlers, run the 'Tree-shake test' from the GitHub Actions menu.

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes — Reviewed the delta since the prior pullfrog review (52f3f7a8, superseded by a force-push; compared the old SHA's file state against current HEAD 0628976a5). Both changes respond to human-reviewer feedback from the August 24–26 reviews:

  • Removed the redundant ArrayExpression re-wrap (wgslGenerator.ts:784-786): d.arrayOf(...)([...]) now returns typeInstantiation(...) directly instead of re-wrapping its result in snip(...) with identical fields. Behavior-preserving; addresses the "just recreating the same snippet" concern.
  • Added sets origin of external arrays to constant (wgslGenerator.test.ts:2042-2051): covers the fallthroughCopyOrigin(arg.origin) copy-branch change, which previously had no coverage.

I verified the new test genuinely pins the fix — reverting fallthroughCopyOrigin(arg.origin) to 'runtime' makes it fail (expected 'runtime' to be 'constant') — and ran tests/tgsl/wgslGenerator.test.ts (90/90 pass). No new issues.

Pullfrog  | View workflow run | Using DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants