-
Notifications
You must be signed in to change notification settings - Fork 25.2k
[dynamo] Fix graph break on calling functions decorated with special context manager #160703
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
🔗 Helpful Links🧪 See artifacts and rendered test results at hud.pytorch.org/pr/160703
Note: Links to docs will display an error until the docs builds have been completed. ✅ No FailuresAs of commit 98f308a with merge base ee1b041 ( This comment was automatically generated by Dr. CI and updates every 15 minutes. |
…context manager As title. This is a follow-up of the previous patch, with the goal of supporting a new pattern that showed up in ComfyUI: https://github.com/comfyanonymous/ComfyUI/blob/644b23ac0b92442b475e44397c62aa8de929d546/comfy/ops.py#L44 Effectively, the semantics of calling a function decorated with a context manager is: ```python ctx_manager(args) def f(x): ... f(x) with ctx_manager(args): f(x) ``` Yes, a fresh context manager instance per invokation, see CPython source code: https://github.com/python/cpython/blob/3.12/Lib/contextlib.py#L119-L122 So Dynamo already 1. knows how to handle the `with ctx_manager(args)` syntax, and has special handling for a few torch native context managers, like `sdpa_kernel` in this patch. 2. can trace through a good chunk (at least the ones that matter in this case) of contextlib. This patch just let Dynamo trace a bit more into contextlib, and then keep the torch-native special cases by moving their handling a bit down the stack, so that no additional logic is introduced -- it's only refactored. This also allows us to get rid of some `_sdpa_kernel_variadic` special handling, since now we will trace through its code, and it boils down to `sdpa_kernel` anyways. ghstack-source-id: 130f92b Pull-Request-resolved: #160703
…context manager As title. This is a follow-up of the previous patch, with the goal of supporting a new pattern that showed up in ComfyUI: https://github.com/comfyanonymous/ComfyUI/blob/644b23ac0b92442b475e44397c62aa8de929d546/comfy/ops.py#L44 Effectively, the semantics of calling a function decorated with a context manager is: ```python ctx_manager(args) def f(x): ... f(x) with ctx_manager(args): f(x) ``` Yes, a fresh context manager instance per invokation, see CPython source code: https://github.com/python/cpython/blob/3.12/Lib/contextlib.py#L119-L122 So Dynamo already 1. knows how to handle the `with ctx_manager(args)` syntax, and has special handling for a few torch native context managers, like `sdpa_kernel` in this patch. 2. can trace through a good chunk (at least the ones that matter in this case) of contextlib. This patch just let Dynamo trace a bit more into contextlib, and then keep the torch-native special cases by moving their handling a bit down the stack, so that no additional logic is introduced -- it's only refactored. This also allows us to get rid of some `_sdpa_kernel_variadic` special handling, since now we will trace through its code, and it boils down to `sdpa_kernel` anyways. ghstack-source-id: 5be04ef Pull-Request-resolved: #160703
if isinstance(args[0], UserFunctionVariable): | ||
fn = args[0].fn | ||
fn_source = args[0].source | ||
# At this point `fn` is the "unwrapped" version of the | ||
# context-managerified function. | ||
if fn is torch.nn.attention.sdpa_kernel.__wrapped__: | ||
args, kwargs = args[1], args[2] | ||
name_to_arg_map = bind_args_cached( | ||
fn, tx, fn_source, args.items, kwargs.items | ||
) | ||
backends = name_to_arg_map["backends"].as_python_constant() | ||
set_priority = name_to_arg_map[ | ||
"set_priority" | ||
].as_python_constant() | ||
return SDPAKernelVariable.create(tx, backends, set_priority) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a TorchCtxManagerClassVariable
that handles special cases of context managers. Could you try to implement this context manager using it?
pytorch/torch/_dynamo/variables/torch.py
Lines 13 to 14 in 30d2f98
TorchCtxManagerClassVariable: Handles torch context managers like torch.no_grad(), autocast, etc. | |
Provides implementations for entering/exiting these contexts during tracing. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was basically moving the sdpa_kernels
special casing out of it, since it's no longer a "class value" anymore after this patch (we'll trace into the actual wrapped sdpa_kernels
as a function value), and I was intercepting the actual context manager construction right here.
Regardless, keeping the logic in TorchCtxManagerClassVariable
might also make things more organized anyways, despite the misnomer. Ideally I'm hoping we just trace through the python code as much as possible eventually, without special casing, to avoid issues like #160684.
…context manager As title. This is a follow-up of the previous patch, with the goal of supporting a new pattern that showed up in ComfyUI: https://github.com/comfyanonymous/ComfyUI/blob/644b23ac0b92442b475e44397c62aa8de929d546/comfy/ops.py#L44 Effectively, the semantics of calling a function decorated with a context manager is: ```python ctx_manager(args) def f(x): ... f(x) #-------> with ctx_manager(args): f(x) ``` Yes, a fresh context manager instance per invokation, see CPython source code: https://github.com/python/cpython/blob/3.12/Lib/contextlib.py#L119-L122 So Dynamo already 1. knows how to handle the `with ctx_manager(args)` syntax, and has special handling for a few torch native context managers, like `sdpa_kernel` in this patch. 2. can trace through a good chunk (at least the ones that matter in this case) of contextlib. This patch just let Dynamo trace a bit more into contextlib, and then keep the torch-native special cases by moving their handling a bit down the stack, so that no additional logic is introduced -- it's only refactored. This also allows us to get rid of some `_sdpa_kernel_variadic` special handling, since now we will trace through its code, and it boils down to `sdpa_kernel` anyways. ghstack-source-id: 364a63b Pull-Request-resolved: #160703
@pytorchbot merge |
Merge startedYour change will be merged once all checks pass (ETA 0-4 Hours). Learn more about merging in the wiki. Questions? Feedback? Please reach out to the PyTorch DevX Team |
…context manager (pytorch#160703) As title. This is a follow-up of the previous patch, with the goal of supporting a new pattern that showed up in ComfyUI: https://github.com/comfyanonymous/ComfyUI/blob/644b23ac0b92442b475e44397c62aa8de929d546/comfy/ops.py#L44 Effectively, the semantics of calling a function decorated with a context manager is: ```python @ctx_manager(args) def f(x): ... f(x) # -----> with ctx_manager(args): f.__wrapped__(x) ``` Yes, a fresh context manager instance per invokation, see CPython source code: https://github.com/python/cpython/blob/3.12/Lib/contextlib.py#L119-L122 So Dynamo already 1. knows how to handle the `with ctx_manager(args)` syntax, and has special handling for a few torch native context managers, like `sdpa_kernel` in this patch. 2. can trace through a good chunk (at least the ones that matter in this case) of contextlib. This patch just let Dynamo trace a bit more into contextlib, and then keep the torch-native special cases by moving their handling a bit down the stack, so that no additional logic is introduced -- it's only refactored. This also allows us to get rid of some `_sdpa_kernel_variadic` special handling, since now we will trace through its code, and it boils down to `sdpa_kernel` anyways. Pull Request resolved: pytorch#160703 Approved by: https://github.com/guilhermeleobas, https://github.com/mlazos ghstack dependencies: pytorch#160684
Stack from ghstack (oldest at bottom):
attention.sdpa_kernel
calls with kwargs #160684As title. This is a follow-up of the previous patch, with the goal of
supporting a new pattern that showed up in ComfyUI:
https://github.com/comfyanonymous/ComfyUI/blob/644b23ac0b92442b475e44397c62aa8de929d546/comfy/ops.py#L44
Effectively, the semantics of calling a function decorated with a
context manager is:
Yes, a fresh context manager instance per invokation, see CPython source code:
https://github.com/python/cpython/blob/3.12/Lib/contextlib.py#L119-L122
So Dynamo already
with ctx_manager(args)
syntax, and hasspecial handling for a few torch native context managers, like
sdpa_kernel
in this patch.case) of contextlib.
This patch just let Dynamo trace a bit more into contextlib, and then
keep the torch-native special cases by moving their handling a bit down
the stack, so that no additional logic is introduced -- it's only
refactored.
This also allows us to get rid of some
_sdpa_kernel_variadic
specialhandling, since now we will trace through its code, and it boils down to
sdpa_kernel
anyways.cc @voznesenskym @penguinwu @EikanWang @jgong5 @Guobing-Chen @XiaobingSuper @zhuhaozhe @blzheng @wenzhe-nrv @jiayisunx @chenyang78 @kadeng @chauhang @amjames @Lucaskabela @mlazos