Skip to content

[inductor] Multi-output custom op ExternKernelOut lowering#176117

Closed
tianrengao wants to merge 10 commits into
gh/tianrengao/29/basefrom
gh/tianrengao/29/head
Closed

[inductor] Multi-output custom op ExternKernelOut lowering#176117
tianrengao wants to merge 10 commits into
gh/tianrengao/29/basefrom
gh/tianrengao/29/head

Conversation

@tianrengao

@tianrengao tianrengao commented Mar 2, 2026

Copy link
Copy Markdown
Contributor

@pytorch-bot

pytorch-bot Bot commented Mar 2, 2026

Copy link
Copy Markdown

🔗 Helpful Links

🧪 See artifacts and rendered test results at hud.pytorch.org/pr/176117

Note: Links to docs will display an error until the docs builds have been completed.

✅ You can merge normally! (1 Unrelated Failure)

As of commit d8993a9 with merge base f0bae19 (image):

UNSTABLE - The following job is marked as unstable, possibly due to flakiness on trunk:

This comment was automatically generated by Dr. CI and updates every 15 minutes.

@pytorch-bot

pytorch-bot Bot commented Mar 2, 2026

Copy link
Copy Markdown

This PR needs a release notes: label

If your changes are user facing and intended to be a part of release notes, please use a label starting with release notes:.

If not, please add the topic: not user facing label.

To add a label, you can comment to pytorchbot, for example
@pytorchbot label "topic: not user facing"

For more information, see
https://github.com/pytorch/pytorch/wiki/PyTorch-AutoLabel-Bot#why-categorize-for-release-notes-and-how-does-it-work.

cc voznesenskym penguinwu EikanWang jgong5 Guobing-Chen XiaobingSuper zhuhaozhe blzheng wenzhe-nrv jiayisunx ipiszy kadeng muchulee8 amjames chauhang aakhundov coconutruben jataylo

[ghstack-poisoned]
cc voznesenskym penguinwu EikanWang jgong5 Guobing-Chen XiaobingSuper zhuhaozhe blzheng wenzhe-nrv jiayisunx ipiszy kadeng muchulee8 amjames chauhang aakhundov coconutruben jataylo

[ghstack-poisoned]

@eellison eellison 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.

would you mind combining the above test coverage pr with this pr

Comment thread torch/_inductor/custom_op_out_lowering.py Outdated
Comment thread torch/_inductor/custom_op_out_lowering.py Outdated
tianrengao added a commit to tianrengao/vllm that referenced this pull request Mar 3, 2026
Switch the scaled_fp4_quant Python wrapper from calling .out (with
pre-allocated buffers) to the functional variant (C++ allocates
internally). This enables PyTorch Inductor (2.12+) to automatically
discover the .out overload via to_out_variant() and manage output
buffers for buffer reuse optimization.

Depends on:
- pytorch/pytorch#175116 (custom op out-variant lowering hook)
- pytorch/pytorch#176117 (multi-output support)

Signed-off-by: tianrengao <terrygao87@gmail.com>
cc voznesenskym penguinwu EikanWang jgong5 Guobing-Chen XiaobingSuper zhuhaozhe blzheng wenzhe-nrv jiayisunx ipiszy kadeng muchulee8 amjames chauhang aakhundov coconutruben jataylo

[ghstack-poisoned]
tianrengao added a commit that referenced this pull request Mar 3, 2026
Extends PR1 single-output lowering to handle multi-output functional
custom ops. Adds CustomOpMultiOutputNode (packed node that emits the
.out() call) and AllocatingMultiOutput (MultiOutput child with
should_allocate=True for buffer reuse). Out arg names from the schema
(e.g. out0, out1, output, output_scale) are used in codegen.

ghstack-source-id: a7014a2
Pull Request resolved: #176117
#175116



cc voznesenskym penguinwu EikanWang jgong5 Guobing-Chen XiaobingSuper zhuhaozhe blzheng wenzhe-nrv jiayisunx ipiszy kadeng muchulee8 amjames chauhang aakhundov coconutruben jataylo

[ghstack-poisoned]
tianrengao added a commit that referenced this pull request Mar 3, 2026
Extends PR1 single-output lowering to handle multi-output functional
custom ops. Adds CustomOpMultiOutputNode (packed node that emits the
.out() call) and AllocatingMultiOutput (MultiOutput child with
should_allocate=True for buffer reuse). Out arg names from the schema
(e.g. out0, out1, output, output_scale) are used in codegen.

ghstack-source-id: a8748a4
Pull Request resolved: #176117
#175116



cc voznesenskym penguinwu EikanWang jgong5 Guobing-Chen XiaobingSuper zhuhaozhe blzheng wenzhe-nrv jiayisunx ipiszy kadeng muchulee8 amjames chauhang aakhundov coconutruben jataylo

[ghstack-poisoned]
tianrengao added a commit that referenced this pull request Mar 4, 2026
Extends PR1 single-output lowering to handle multi-output functional
custom ops. Adds CustomOpMultiOutputNode (packed node that emits the
.out() call) and AllocatingMultiOutput (MultiOutput child with
should_allocate=True for buffer reuse). Out arg names from the schema
(e.g. out0, out1, output, output_scale) are used in codegen.

ghstack-source-id: 169dc39
Pull Request resolved: #176117
#175116



cc voznesenskym penguinwu EikanWang jgong5 Guobing-Chen XiaobingSuper zhuhaozhe blzheng wenzhe-nrv jiayisunx ipiszy kadeng muchulee8 amjames chauhang aakhundov coconutruben jataylo

[ghstack-poisoned]
tianrengao added a commit that referenced this pull request Mar 4, 2026
Extends PR1 single-output lowering to handle multi-output functional
custom ops. Adds CustomOpMultiOutputNode (packed node that emits the
.out() call) and AllocatingMultiOutput (MultiOutput child with
should_allocate=True for buffer reuse). Out arg names from the schema
(e.g. out0, out1, output, output_scale) are used in codegen.

ghstack-source-id: 0e109f6
Pull Request resolved: #176117
@tianrengao tianrengao requested review from drisspg and eellison March 4, 2026 06:59

@eellison eellison 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.

couple comments.

Comment on lines +220 to +236

def _codegen_input_args(node: ir.ExternKernel) -> list[str]:
"""Codegen positional + constant args, excluding out args."""
assert ir.is_node_sequence(node.inputs)
args = [x.codegen_reference() for x in node.inputs] # type: ignore[union-attr]
for const in node.constant_args:
args.append(V.graph.wrapper_code.val_to_arg_str(const))
return args


def _codegen_kwargs(node: ir.ExternKernel, skip_names: OrderedSet[str]) -> list[str]:
"""Codegen keyword args, skipping out arg names (appended separately)."""
result = []
for k, v in node.kwargs.items():
if k not in skip_names:
result.append(f"{k}={V.graph.wrapper_code.val_to_arg_str(v)}")
return result

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.

Can we normalize this, with the rest of the codebase ? see:

class ExternKernelOutLine(WrapperLine):

this is in a completely different place.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done. Added ExternKernelMultiOutLine(WrapperLine) right after ExternKernelOutLine in wrapper.py and removed the entire custom_op_out_lowering.py

return torch.ops.mylib.split_add, torch.ops.mylib.split_add.out

@parametrize("device", DEVICES)
def test_multi_output_lowered_to_out(self, device):

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.

Does this work with cpp wrapper ? can we either add support for this or fallback if its not supported ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Added cpp_wrapper guard. multioutput .out lowering is skipped under cpp wrapper, falling back to standard FallbackKernel codegen.

cpp wrapper support can be added later when needed.

Comment on lines +107 to +113
def try_lower_multi_output_to_out_variant(
kernel: OpOverload,
example_output: Any,
packed: ir.FallbackKernel,
*,
has_unaligned_input: bool = False,
) -> Optional[Sequence[AllocatingMultiOutput]]:

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.

if it doesn't make sense to refactor ExternKernelOut to work with the new changes (it may not,)can you add a new class ExternKernelMultiOut or something? and normalize that to where ExternKernel is in the codebase.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, ExternKernelOut can't be extended for multi-output because it's a single-buffer node.

Added ExternKernelMultiOut in ir.py. It inherits FallbackKernel to reuse codegen_args/unflatten_args infrastructure, and overrides codegen() to emit .out() calls. Also deleted custom_op_out_lowering.py

#175116



cc voznesenskym penguinwu EikanWang jgong5 Guobing-Chen XiaobingSuper zhuhaozhe blzheng wenzhe-nrv jiayisunx ipiszy kadeng muchulee8 amjames chauhang aakhundov coconutruben jataylo mlazos

[ghstack-poisoned]
tianrengao added a commit that referenced this pull request Mar 4, 2026
Extends PR1 single-output lowering to handle multi-output functional
custom ops. Adds CustomOpMultiOutputNode (packed node that emits the
.out() call) and AllocatingMultiOutput (MultiOutput child with
should_allocate=True for buffer reuse). Out arg names from the schema
(e.g. out0, out1, output, output_scale) are used in codegen.

ghstack-source-id: 70ba508
Pull Request resolved: #176117
#175116



cc voznesenskym penguinwu EikanWang jgong5 Guobing-Chen XiaobingSuper zhuhaozhe blzheng wenzhe-nrv jiayisunx ipiszy kadeng muchulee8 amjames chauhang aakhundov coconutruben jataylo mlazos

[ghstack-poisoned]
tianrengao added a commit that referenced this pull request Mar 5, 2026
Extends PR1 single-output lowering to handle multi-output functional
custom ops. Adds CustomOpMultiOutputNode (packed node that emits the
.out() call) and AllocatingMultiOutput (MultiOutput child with
should_allocate=True for buffer reuse). Out arg names from the schema
(e.g. out0, out1, output, output_scale) are used in codegen.

ghstack-source-id: 95cbcd6
Pull Request resolved: #176117
#175116



cc voznesenskym penguinwu EikanWang jgong5 Guobing-Chen XiaobingSuper zhuhaozhe blzheng wenzhe-nrv jiayisunx ipiszy kadeng muchulee8 amjames chauhang aakhundov coconutruben jataylo mlazos

[ghstack-poisoned]
tianrengao added a commit that referenced this pull request Mar 5, 2026
Extends PR1 single-output lowering to handle multi-output functional
custom ops. Adds CustomOpMultiOutputNode (packed node that emits the
.out() call) and AllocatingMultiOutput (MultiOutput child with
should_allocate=True for buffer reuse). Out arg names from the schema
(e.g. out0, out1, output, output_scale) are used in codegen.

ghstack-source-id: 61e5d34
Pull Request resolved: #176117
@tianrengao

Copy link
Copy Markdown
Contributor Author

@pytorchbot merge -i

@pytorch-bot pytorch-bot Bot added the ciflow/trunk Trigger trunk jobs on your pull request label Mar 5, 2026
@pytorchmergebot

Copy link
Copy Markdown
Collaborator

Merge started

Your change will be merged while ignoring the following 1 checks: inductor / inductor-cpu-test / test (cpu_inductor_torchbench, 1, 2, linux.2xlarge.amx, unstable)

Learn more about merging in the wiki.

Questions? Feedback? Please reach out to the PyTorch DevX Team

Advanced Debugging
Check the merge workflow status
here

sandy-gags pushed a commit to sandy-gags/pytorch that referenced this pull request Mar 12, 2026
Extends PR1 single-output lowering to handle multi-output functional
custom ops. Adds CustomOpMultiOutputNode (packed node that emits the
.out() call) and AllocatingMultiOutput (MultiOutput child with
should_allocate=True for buffer reuse). Out arg names from the schema
(e.g. out0, out1, output, output_scale) are used in codegen.

ghstack-source-id: 0e1d843
Pull Request resolved: pytorch/pytorch#176117
tianrengao added a commit to tianrengao/vllm that referenced this pull request Mar 13, 2026
The out_variant tag is not yet available in torch==2.10.0.
See pytorch/pytorch#176117.

Signed-off-by: tianrengao <terrygao87@gmail.com>
EmanueleCoradin pushed a commit to EmanueleCoradin/pytorch that referenced this pull request Mar 30, 2026
@github-actions github-actions Bot deleted the gh/tianrengao/29/head branch April 5, 2026 02:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants