Skip to content

Support OutputCodeOptions(allow_helion_deps=False) for the Pallas backend (TorchTPU) - #3184

Merged
AmesingFlank merged 1 commit into
mainfrom
AmesingFlank/stack/98
Jul 31, 2026
Merged

Support OutputCodeOptions(allow_helion_deps=False) for the Pallas backend (TorchTPU)#3184
AmesingFlank merged 1 commit into
mainfrom
AmesingFlank/stack/98

Conversation

@AmesingFlank

@AmesingFlank AmesingFlank commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Stacked PRs:


Support OutputCodeOptions(allow_helion_deps=False) for the Pallas backend (TorchTPU)

Implement PallasBackend.dependency_free_launcher_info so
to_code(options=OutputCodeOptions(allow_helion_deps=False)) works for Pallas
(TorchTPU) kernels: the emitted module inlines the dependency-free Pallas
launcher as a local helion.runtime shim, and its only runtime deps are
torch + jax.

Example (kernel bound with backend="pallas"):

code = bound.to_code(cfg, options=OutputCodeOptions(allow_helion_deps=False))

emits a module whose deps are torch + jax (no helion import):

import torch, types
helion = types.SimpleNamespace(runtime=_make_helion_runtime())  # inlined Pallas
    # launcher; topk/worklist helpers embedded (not imported)
def _helion_add(x, y, out): ...
def add(x, y, *, _launcher=_default_pallas_launcher):  # torch.Tensor -> torch.Tensor

Pallas kernels call two helion-defined pure-jax helpers in-kernel --
divide_filter_topk (aten.topk lowering) and flatten_worklist
(compact-worklist builder). Regular to_code imports them from helion (added as
conditional library_imports entries); the dependency-free path drops those
imports and embeds the helper source instead (embedded_helper_source, called
only by the standalone builders). Their modules carry a note to stay free of any
helion import so the embed stays self-contained.

This folds in the previously separate "Embed in-kernel Pallas runtime helpers"
change: embedding is now a dependency-free-only step rather than applied to every
to_code, so regular output is import-based and only standalones embed.

@AmesingFlank
AmesingFlank force-pushed the AmesingFlank/stack/98 branch from e2f682b to ab11374 Compare July 28, 2026 16:02
@AmesingFlank
AmesingFlank force-pushed the AmesingFlank/stack/97 branch from c6b5c2a to 1003016 Compare July 28, 2026 16:02
@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Meta Open Source bot. label Jul 28, 2026
@AmesingFlank
AmesingFlank changed the base branch from AmesingFlank/stack/97 to main July 28, 2026 17:39
@AmesingFlank
AmesingFlank changed the base branch from main to AmesingFlank/stack/97 July 28, 2026 17:39
@AmesingFlank
AmesingFlank changed the base branch from AmesingFlank/stack/97 to main July 28, 2026 20:09
@AmesingFlank
AmesingFlank force-pushed the AmesingFlank/stack/98 branch from ab11374 to 2b10a7a Compare July 28, 2026 20:09
@AmesingFlank
AmesingFlank changed the base branch from main to AmesingFlank/stack/97 July 28, 2026 20:10
@AmesingFlank
AmesingFlank changed the base branch from AmesingFlank/stack/97 to main July 28, 2026 21:14
@AmesingFlank
AmesingFlank force-pushed the AmesingFlank/stack/98 branch from 2b10a7a to 55b6703 Compare July 28, 2026 21:14
@AmesingFlank
AmesingFlank changed the base branch from main to AmesingFlank/stack/97 July 28, 2026 21:15
AmesingFlank added a commit that referenced this pull request Jul 28, 2026
Add the Pallas precompiler beside its launcher, in
`helion/runtime/pallas/precompile.py` (`PallasPrecompiler`), and register it in
the orchestrator's per-backend dispatch. It uses the backend-neutral default
flow -- inline the dependency-free Pallas launcher
(`helion/runtime/pallas/launcher.py`) -- so a precompiled Pallas kernel runs on
TPU with torch + jax and no helion at runtime. (`jax_fn=True` is added next.)

Verified on the TPU pod: precompiling a Pallas `add` produces a standalone with
no `import helion`, and running it on TPU returns correct results.
`ruff`/`pyrefly` clean (83 baseline).

stack-info: PR: #3184, branch: AmesingFlank/stack/98
@AmesingFlank
AmesingFlank changed the base branch from AmesingFlank/stack/97 to main July 28, 2026 22:27
@AmesingFlank
AmesingFlank force-pushed the AmesingFlank/stack/98 branch from 55b6703 to 83fa975 Compare July 28, 2026 22:27
@AmesingFlank
AmesingFlank changed the base branch from main to AmesingFlank/stack/97 July 28, 2026 22:27
@AmesingFlank
AmesingFlank changed the base branch from AmesingFlank/stack/97 to main July 29, 2026 00:03
@AmesingFlank
AmesingFlank changed the base branch from main to AmesingFlank/stack/97 July 29, 2026 00:04
@AmesingFlank
AmesingFlank changed the base branch from AmesingFlank/stack/97 to main July 29, 2026 05:05
@AmesingFlank
AmesingFlank changed the base branch from AmesingFlank/stack/95 to main July 30, 2026 03:47
@AmesingFlank
AmesingFlank force-pushed the AmesingFlank/stack/98 branch from ad120fb to 45ebee7 Compare July 30, 2026 03:47
@AmesingFlank
AmesingFlank changed the base branch from main to AmesingFlank/stack/95 July 30, 2026 03:48
AmesingFlank added a commit that referenced this pull request Jul 30, 2026
Add the Pallas precompiler beside its launcher, in
`helion/runtime/pallas/precompile.py` (`PallasPrecompiler`), and register it in
the orchestrator's per-backend dispatch. It uses the backend-neutral default
flow -- inline the dependency-free Pallas launcher
(`helion/runtime/pallas/launcher.py`) -- so a precompiled Pallas kernel runs on
TPU with torch + jax and no helion at runtime. (`jax_fn=True` is added next.)

Verified on the TPU pod: precompiling a Pallas `add` produces a standalone with
no `import helion`, and running it on TPU returns correct results.
`ruff`/`pyrefly` clean (83 baseline).

stack-info: PR: #3184, branch: AmesingFlank/stack/98
@AmesingFlank
AmesingFlank changed the base branch from AmesingFlank/stack/95 to main July 30, 2026 08:14
@AmesingFlank
AmesingFlank force-pushed the AmesingFlank/stack/98 branch from 45ebee7 to cdf0bc3 Compare July 30, 2026 08:15
@AmesingFlank AmesingFlank changed the title Make helion.precompile support the Pallas backend (TorchTPU) Support to_code(allow_helion_deps=False) for the Pallas backend (TorchTPU) Jul 30, 2026
@AmesingFlank
AmesingFlank changed the base branch from main to AmesingFlank/stack/95 July 30, 2026 08:15
@AmesingFlank
AmesingFlank changed the base branch from AmesingFlank/stack/95 to main July 30, 2026 15:31
@AmesingFlank
AmesingFlank force-pushed the AmesingFlank/stack/98 branch from cdf0bc3 to 012f471 Compare July 30, 2026 15:31
@AmesingFlank AmesingFlank changed the title Support to_code(allow_helion_deps=False) for the Pallas backend (TorchTPU) Support OutputCodeOptions(allow_helion_deps=False) for the Pallas backend (TorchTPU) Jul 30, 2026
@AmesingFlank
AmesingFlank changed the base branch from main to AmesingFlank/stack/95 July 30, 2026 15:31
AmesingFlank added a commit that referenced this pull request Jul 30, 2026
…ackend (TorchTPU)

Implement `PallasBackend.dependency_free_launcher_info` so
`to_code(options=OutputCodeOptions(allow_helion_deps=False))` works for Pallas
(TorchTPU) kernels: the emitted module inlines the dependency-free Pallas
launcher as a local `helion.runtime` shim, and its only runtime deps are
`torch` + `jax`.

Pallas kernels call two helion-defined pure-`jax` helpers in-kernel --
`divide_filter_topk` (aten.topk lowering) and `flatten_worklist`
(compact-worklist builder). Regular `to_code` imports them from helion (added as
conditional `library_imports` entries); the dependency-free path drops those
imports and embeds the helper source instead (`embedded_helper_source`, called
only by the standalone builders). Their modules carry a note to stay free of any
`helion` import so the embed stays self-contained.

This folds in the previously separate "Embed in-kernel Pallas runtime helpers"
change: embedding is now a dependency-free-only step rather than applied to every
`to_code`, so regular output is import-based and only standalones embed.

stack-info: PR: #3184, branch: AmesingFlank/stack/98
@AmesingFlank
AmesingFlank changed the base branch from AmesingFlank/stack/95 to main July 30, 2026 17:36
@AmesingFlank
AmesingFlank force-pushed the AmesingFlank/stack/98 branch from 012f471 to 9e7c129 Compare July 30, 2026 17:37
@AmesingFlank
AmesingFlank changed the base branch from main to AmesingFlank/stack/95 July 30, 2026 17:37
@AmesingFlank
AmesingFlank changed the base branch from AmesingFlank/stack/95 to main July 30, 2026 18:06
@AmesingFlank
AmesingFlank force-pushed the AmesingFlank/stack/98 branch from 9e7c129 to 9da8bc7 Compare July 30, 2026 18:07
@AmesingFlank
AmesingFlank changed the base branch from main to AmesingFlank/stack/95 July 30, 2026 18:07
@AmesingFlank
AmesingFlank marked this pull request as ready for review July 30, 2026 18:08
@AmesingFlank
AmesingFlank marked this pull request as draft July 30, 2026 19:10
@AmesingFlank
AmesingFlank changed the base branch from AmesingFlank/stack/95 to main July 30, 2026 19:10
@AmesingFlank
AmesingFlank force-pushed the AmesingFlank/stack/98 branch from 9da8bc7 to d7a3a2c Compare July 30, 2026 19:10
@AmesingFlank
AmesingFlank changed the base branch from main to AmesingFlank/stack/95 July 30, 2026 19:10
…ackend (TorchTPU)

Implement `PallasBackend.dependency_free_launcher_info` so
`to_code(options=OutputCodeOptions(allow_helion_deps=False))` works for Pallas
(TorchTPU) kernels: the emitted module inlines the dependency-free Pallas
launcher as a local `helion.runtime` shim, and its only runtime deps are
`torch` + `jax`.

Example (kernel bound with backend="pallas"):

    code = bound.to_code(cfg, options=OutputCodeOptions(allow_helion_deps=False))

emits a module whose deps are `torch` + `jax` (no `helion` import):

    import torch, types
    helion = types.SimpleNamespace(runtime=_make_helion_runtime())  # inlined Pallas
        # launcher; topk/worklist helpers embedded (not imported)
    def _helion_add(x, y, out): ...
    def add(x, y, *, _launcher=_default_pallas_launcher):  # torch.Tensor -> torch.Tensor

Pallas kernels call two helion-defined pure-`jax` helpers in-kernel --
`divide_filter_topk` (aten.topk lowering) and `flatten_worklist`
(compact-worklist builder). Regular `to_code` imports them from helion (added as
conditional `library_imports` entries); the dependency-free path drops those
imports and embeds the helper source instead (`embedded_helper_source`, called
only by the standalone builders). Their modules carry a note to stay free of any
`helion` import so the embed stays self-contained.

This folds in the previously separate "Embed in-kernel Pallas runtime helpers"
change: embedding is now a dependency-free-only step rather than applied to every
`to_code`, so regular output is import-based and only standalones embed.

stack-info: PR: #3184, branch: AmesingFlank/stack/98
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Meta Open Source bot.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants