Skip to content

Vendor the fused JIT and drop the finch-tensor dependency - #155

Open
kylebd99 wants to merge 3 commits into
mainfrom
kbd/vendor-fused-jit
Open

kylebd99 wants to merge 3 commits into
mainfrom
kbd/vendor-fused-jit

Conversation

@kylebd99

@kylebd99 kylebd99 commented Oct 2, 2026

Copy link
Copy Markdown
Collaborator

Why

gl.jit was a thin wrapper around finch.finch_fused.jit. It swapped in Galley's runtime by overwriting defer, compute and maybedefer in the generated function's globals. That ties galley-jl-python to finch-tensor's internals: any change to how finch-tensor's JIT calls its runtime breaks Galley. The finch-tensor JIT is about to change in exactly that way, as it gains fusion across function calls. Copying the JIT here lets the two packages evolve independently.

What

  • New galley_jl_python.fused package, copied from finch.finch_fused on finch-tensor main: nodes, parser, cfg_builder, dataflow and jit.
    • Galley's defer/compute/maybedefer now live in fused/dataflow.py and are used directly, with no globals patching.
    • The finch type-system hooks (result_type, ftype) are removed, since nothing in the pipeline reads them.
  • fused/symbolic.py holds the parts of finch.symbolic the JIT needs: terms, Rewrite/PostWalk/Chain, Namespace, Context, and the CFG and dataflow classes.
  • Removed finch_fused.py and the finch-tensor dependency.
  • gl.jit(f, ctx=None) keeps its signature. ctx was already ignored.

Tests

  • New tests/test_fused_compiler.py:
    • finch-tensor's parser, round-trip, CFG and liveness tests, ported to the vendored code.
    • A test that importing galley and running gl.jit never imports finch.
  • Results: tests/test_fused.py plus the new file, 17 passed. Full suite, excluding array-API, 966 passed, 45 skipped, 20 xfailed.

🤖 Generated with Claude Code

kylebd99 and others added 2 commits October 2, 2026 13:08
`gl.jit` reused `finch.finch_fused` and swapped in Galley's runtime by
overwriting `defer`, `compute` and `maybedefer` in the generated function's
globals. Copy the fused JIT (and the parts of `finch.symbolic` it needs) into
`galley_jl_python.fused`, with Galley's runtime wired in directly, so the two
packages can evolve independently. Also port finch-tensor's parser, CFG and
liveness tests for it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Port fixes made to finch-tensor's finch_fused:
- `|`/`&` were lowered to `or`/`and`, since both shared `operator.or_`/`and_`.
- A for-loop target was never defined in the CFG, so using it in the body
  made it live on entry and raised UnboundLocalError.
- `break` could not be parsed (it was matched as an expression) or lowered.
- Bare call statements crashed the CFG builder.
- Conditional expressions lowered to an unrepresentable lambda, and distinct
  callables sharing a `__name__` clobbered each other in the generated globals.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kylebd99

kylebd99 commented Oct 2, 2026

Copy link
Copy Markdown
Collaborator Author

Added 4aad33d, which ports finch-tensor's finch_fused bug fixes to the vendored JIT:

  • |/& are no longer lowered to or/and.
  • For-loop variables are defined in the CFG.
  • break statements and bare call statements are supported.
  • Conditional expressions can be emitted.
  • Distinct callables with the same name no longer clobber each other.

Each has a regression test in tests/test_fused_compiler.py. All 23 fused tests pass.

`dtype` read the element type from the swizzle's body, which a lazy tensor
does not have, so any elementwise operation between a lazy tensor and a Python
scalar (e.g. `A * 2` inside `gl.jit`) raised a FieldError. Take `eltype` of
the swizzle itself, which works for both.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kylebd99

kylebd99 commented Oct 2, 2026

Copy link
Copy Markdown
Collaborator Author

Added f46ddde: Tensor.dtype now takes eltype of the swizzle instead of its body. Lazy tensors have no body, so an elementwise op between a lazy tensor and a Python scalar (e.g. A * 2 inside gl.jit) raised a FieldError. There's a regression test in tests/test_fused.py. Full suite: 973 passed.

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.

1 participant