Numba: Fuse Elemwise + Reduction#2227
Merged
ricardoV94 merged 4 commits intoJul 15, 2026
Merged
Conversation
ricardoV94
commented
Jun 15, 2026
ricardoV94
commented
Jun 15, 2026
ricardoV94
force-pushed
the
reduction_fusion_with_scope_markers
branch
from
June 16, 2026 11:50
777ed4c to
605789e
Compare
Member
|
I had another look at the alias-scope metadata. This is a bit scary, because it would lead to quite strange problems if we get this wrong, and it is not easy to reason through properly, but it does look correct to me. |
ricardoV94
force-pushed
the
reduction_fusion_with_scope_markers
branch
3 times, most recently
from
July 7, 2026 09:19
237f039 to
51d42ab
Compare
ricardoV94
marked this pull request as ready for review
July 7, 2026 09:30
ricardoV94
force-pushed
the
reduction_fusion_with_scope_markers
branch
from
July 7, 2026 12:34
51d42ab to
7fdc405
Compare
ricardoV94
added a commit
to ricardoV94/pytensor
that referenced
this pull request
Jul 9, 2026
…e fusion The rebase onto post-pymc-devs#2227 upstream brought in tests that assume the removed AdvancedIncSubtensor1 class and the deleted undo_take_reshape_for_fusion rewrite: - test_local_set_to_inc_subtensor_duplicate_indices: assert on the general AdvancedIncSubtensor (the set->inc unique-index guard still fires correctly); drop the .including() of the now-deleted conversion rewrites. - test_regrouped_gather: remove it. It fused a gather whose result is reshaped to a runtime shape (s0, s1), which stays an opaque Reshape (SplitDims can't be proven), so with undo_take_reshape_for_fusion gone it no longer fuses. Plain ND-take fusion is unaffected (transform_take emits a general AdvancedSubtensor directly). Fix the stale docstring reference in test_nd_index_axis1.
ricardoV94
added a commit
to ricardoV94/pytensor
that referenced
this pull request
Jul 14, 2026
…e fusion The rebase onto post-pymc-devs#2227 upstream brought in tests that assume the removed AdvancedIncSubtensor1 class and the deleted undo_take_reshape_for_fusion rewrite: - test_local_set_to_inc_subtensor_duplicate_indices: assert on the general AdvancedIncSubtensor (the set->inc unique-index guard still fires correctly); drop the .including() of the now-deleted conversion rewrites. - test_regrouped_gather: remove it. It fused a gather whose result is reshaped to a runtime shape (s0, s1), which stays an opaque Reshape (SplitDims can't be proven), so with undo_take_reshape_for_fusion gone it no longer fuses. Plain ND-take fusion is unaffected (transform_take emits a general AdvancedSubtensor directly). Fix the stale docstring reference in test_nd_index_axis1.
An output consumed by several eligible CAReduces previously disqualified itself entirely (the detection required exactly one reduce client). Peel one extra reduction per rewrite pass onto a duplicate output until each reduction has its own copy, so e.g. [sum(f), max(f), prod(f), f] becomes a single FusedElemwise with three fused reductions.
sum(x[idx]) had no Elemwise for FuseElemwise to anchor on, so the gather materialized and the reduction stayed external. A new pre-rewrite wraps such reductions in an identity Elemwise (covering the bare AdvancedSubtensor1, axis-swap DimShuffle and flattened-ND-index Reshape forms), letting gather, identity and reduction collapse into one fused loop.
ricardoV94
force-pushed
the
reduction_fusion_with_scope_markers
branch
from
July 15, 2026 08:21
7fdc405 to
7a27829
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Extends #2015 to also fuse CAReduce with Elemwise or IndexedELemwise (now renamed FusedElemwise).
This sometimes actually causes regressions without numba/llvmlite#895 as it prevents auto-vectorization numba was doing when the Ops weren't fused.
So I did the only logical thing and patched llvmlite from within PyTensor.
Results on the same benchmark we focused on for IndexedElemwise: https://ricardov94.github.io/pymc-model-catalogue/experiments.html#base=fuse_reduction_curated_base&compare=reduction_fusion_vs_nonfused
This is one of the ways in which JAX sometimes beats us on the CPU
Closes #224