# Disabling Codegen-Specific Fusions in TorchInductor for Per-Op Kernel Generation

**URL:** <https://dev-discuss.pytorch.org/t/disabling-codegen-specific-fusions-in-torchinductor-for-per-op-kernel-generation/3226>\
**Category:** compiler\
**Created:** [August 29, 2025, 10:43pm UTC](https://dev-discuss.pytorch.org/t/disabling-codegen-specific-fusions-in-torchinductor-for-per-op-kernel-generation/3226 "2025-08-29T22:43:31Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![skv66](https://yyz2.discourse-cdn.com/flex036/user_avatar/dev-discuss.pytorch.org/skv66/32/2885_2.png) [@skv66](https://dev-discuss.pytorch.org/u/skv66)\
**Post date:** [August 29, 2025, 10:43pm UTC](https://dev-discuss.pytorch.org/t/disabling-codegen-specific-fusions-in-torchinductor-for-per-op-kernel-generation/3226/1 "2025-08-29T22:43:31Z")

</div>

Hi all,

I’m currently working on benchmarking **TorchInductor’s optimization impact** by selectively disabling various fusion and scheduling passes. So far, I have:

1. Disabled **inlining optimizations (**[Previous Post](https://dev-discuss.pytorch.org/t/how-to-turn-off-inlining-force-materialization-in-torchinductor-during-torch-compile/3198))
2. Disabled **scheduler fusions**
3. Disabled all FX-level fusion passes registered

With these changes, I now want to focus specifically on **CPP & Triton**  **codegen fusions** — the ones happening during kernel generation in Inductor after the scheduler.

My goal is to:

1. **Generate one kernel per node/operation** (instead of fused multi-op kernels).

2. Understand **how much these codegen-specific fusions contribute** to TorchInductor’s overall performance gains, compared to other optimizations like scheduling and inlining.

Questions:

1. How can I **disable codegen fusions entirely** so that **TorchInductor generates one kernel per node/operation** instead of fusing multiple ops? (Are there any flags?)
2. How much do these **codegen-specific fusions** contribute to TorchInductor’s overall performance? (Were **codegen fusions** part of the “fusion” **performance speedups** reported in the **PyTorch 2.0 paper**?)

Thanks!

Shriraj

---

<div class="post-metadata">

**Author:** ![jansel](https://yyz2.discourse-cdn.com/flex036/user_avatar/dev-discuss.pytorch.org/jansel/32/74_2.png) [@jansel](https://dev-discuss.pytorch.org/u/jansel)\
**Post date:** [September 4, 2025, 12:59am UTC](https://dev-discuss.pytorch.org/t/disabling-codegen-specific-fusions-in-torchinductor-for-per-op-kernel-generation/3226/2 "2025-09-04T00:59:54Z")

</div>

You can disable fusions by adding `return False` to the top of:

> <https://github.com/pytorch/pytorch/blob/9458d1ac3bd70c2af316a8ba95d2c6c9c1199c9c/torch/_inductor/choices.py#L301-L315>

I’m not sure what you mean by codegen fusions versus scheduler fusions. Fusions always happen in the scheduler.

---

<div class="post-metadata">

**Author:** ![skv66](https://yyz2.discourse-cdn.com/flex036/user_avatar/dev-discuss.pytorch.org/skv66/32/2885_2.png) [@skv66](https://dev-discuss.pytorch.org/u/skv66)\
**Post date:** [September 4, 2025, 2:02am UTC](https://dev-discuss.pytorch.org/t/disabling-codegen-specific-fusions-in-torchinductor-for-per-op-kernel-generation/3226/3 "2025-09-04T02:02:29Z")

</div>

Thanks for the response! I think I may not have framed my question clearly before, so let me clarify.

I’ve **already disabled scheduler fusions** (e.g., via `can_fuse` and related heuristics) and also **disabled inlining optimizations**.

However, I’m noticing that even with scheduler fusions disabled, **some generated kernels still contain multiple operations**.

> E.g. in the output\_code.py file I still see a function called _ **cpp\_fused** \_\_native\_batch\_norm\_legit\_no\_training\_add\_relu\_3,_ this suggests that **multiple ops** (`batch_norm`, `max_pool2d`, `relu`) are still **being fused inside the generated C++ kernel** , even though I’ve disabled all scheduler fusions.

 ![image](https://canada1.discourse-cdn.com/flex036/uploads/pytorch1/original/2X/c/c52492201f9a7879b3e20fd0e248cc217ce7b67c.png)

I’m trying to **quantify the contribution** of each optimization stage in TorchInductor — to understand their individual impact on TorchInductor’s performance.

So I wanted to confirm a couple of things:

1. Are there **fusions/optimizations** happening in **`torch/_inductor/codegen/cpp.py`** or **`triton.py`** that are **separate from scheduler fusions**? Can I get down to one OP per Kernel?

2. In the **PyTorch 2.0 paper** , were these potential **fusions** included when reporting the performance speedups?

Thanks!

---

<div class="post-metadata">

**Author:** ![jansel](https://yyz2.discourse-cdn.com/flex036/user_avatar/dev-discuss.pytorch.org/jansel/32/74_2.png) [@jansel](https://dev-discuss.pytorch.org/u/jansel)\
**Post date:** [September 4, 2025, 2:32am UTC](https://dev-discuss.pytorch.org/t/disabling-codegen-specific-fusions-in-torchinductor-for-per-op-kernel-generation/3226/4 "2025-09-04T02:32:36Z")

</div>

You could try adding a call to self.flush() after loop:

[https://github.com/pytorch/pytorch/blob/57278d45f046d4f89f45d373b1af4dd56934ff24/torch/\_inductor/scheduler.py#L4981](https://github.com/pytorch/pytorch/blob/57278d45f046d4f89f45d373b1af4dd56934ff24/torch/_inductor/scheduler.py#L4994)

If that fixes it then those weren’t fusions, it is just a quirk of how the C++ backend does function boundaries to avoid creating a new `omp for` blocks. For C++ a fusion would produce a single loop, while that would produce two.
