-
Notifications
You must be signed in to change notification settings - Fork 26.3k
[dynamo] prevent recompilation limit exceeded on external_utils.wrap_inline #163503
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
base: gh/williamwen42/297/base
Are you sure you want to change the base?
Conversation
[ghstack-poisoned]
🔗 Helpful Links🧪 See artifacts and rendered test results at hud.pytorch.org/pr/163503
Note: Links to docs will display an error until the docs builds have been completed. ❌ 29 New Failures, 4 Cancelled JobsAs of commit b2d00f6 with merge base 93bc987 ( NEW FAILURES - The following jobs have failed:
CANCELLED JOBS - The following jobs were cancelled. Please retry:
This comment was automatically generated by Dr. CI and updates every 15 minutes. |
…ine" This will prevent recompilations due to wrap_inline's guard on `fn` from hitting the recompilation limit. cc voznesenskym penguinwu EikanWang jgong5 Guobing-Chen XiaobingSuper zhuhaozhe blzheng wenzhe-nrv jiayisunx chenyang78 kadeng chauhang amjames Lucaskabela [ghstack-poisoned]
| if fn not in _wrap_inline_cache: | ||
| _wrap_inline_cache[fn] = deepcopy_code(inner.__code__) # type: ignore[attr-defined] | ||
|
|
||
| inner.__code__ = _wrap_inline_cache[fn] # type: ignore[attr-defined] |
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.
Checking my understanding:
Given different functions f1 and f2, your PR makes wrap_inline(f1) and wrap_inline(f2) have different code objects. Wouldn't that trigger recompilation (as opposed to "don't recompile" as you documented)?
On the other hand, given the same f, existing code (without your PR) already have inner.__code__ being the same for multiple wrap_inline(f) calls, so there'll be no recompilation anyways, e.g.,
import torch
def f(x):
return x + 1
f1 = torch._dynamo.external_utils.wrap_inline(f)
f2 = torch._dynamo.external_utils.wrap_inline(f)
f1 = torch.compile(f1, backend="eager")
f2 = torch.compile(f2, backend="eager")
f1(torch.rand(10))
f2(torch.rand(10))Could you create a minimal example to show what exactly is causing unwanted recompilation over wrap_inline(...)?
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.
Given different functions f1 and f2, your PR makes wrap_inline(f1) and wrap_inline(f2) have different code objects. Wouldn't that trigger recompilation (as opposed to "don't recompile" as you documented)?
I think I got it, by returning a new code object, you are changing recompilations into compilation over different frames (i.e., code objects).
So this is mainly for compiling a wrap_inline-ed function at top level (or after graph breaks, however that might get triggered). But you still want to treat different instances of wrap_inline(f)s (with same input function object) as the same frame for compilation (basically my example), thus the cache.
Curious, why are we hitting this case now?
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.
Minimal example is in the added unit test.
I'm hitting this case now because my wrapped nested graph break tests add an additional frame to each top-level compile call through wrap_inline - but then this causes recompilation limits to be exceeded. I then figured that this problem could happen more generally with wrap_inline - if we compile enough top level functions that are wrap_inline'd, then we would suddenly start hitting the recompile limit.
The current problem with this PR is that we create a new wrapper with a new code object for each instance of the function, which is problematic for two instances of the function with the same code object. This PR would then compile the inner function twice.
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'm hitting this case now because my wrapped nested graph break tests add an additional frame to each top-level compile call through wrap_inline
Makes sense, I assume this is only for the tests, i.e., not fundamental to nested graph break use cases in the wild? If so then I think it's totally okay to lazy evaluate the "different func objects but same code objects" problem.
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.
Yeah, this is not fundamental to nested graph breaks.
StrongerXi
left a comment
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'd like to understand why we are hitting this problem for wrap_inline, etc. now. Because in theory this is a dynamo problem for all non-inplace function wrappers.
…utils.wrap_inline" This will prevent recompilations (i.e. logs to TORCH_LOGS="recompiles") due to wrap_inline's guard on `fn`. If we call wrap_inline on enough different functions, we would hit the recompile limit. cc voznesenskym penguinwu EikanWang jgong5 Guobing-Chen XiaobingSuper zhuhaozhe blzheng wenzhe-nrv jiayisunx chenyang78 kadeng chauhang amjames Lucaskabela [ghstack-poisoned]
…utils.wrap_inline" This will prevent recompilations (i.e. logs to TORCH_LOGS="recompiles") due to wrap_inline's guard on `fn`. If we call wrap_inline on enough different functions, we would hit the recompile limit. cc voznesenskym penguinwu EikanWang jgong5 Guobing-Chen XiaobingSuper zhuhaozhe blzheng wenzhe-nrv jiayisunx chenyang78 kadeng chauhang amjames Lucaskabela [ghstack-poisoned]
…utils.wrap_inline" This will prevent recompilations (i.e. logs to TORCH_LOGS="recompiles") due to wrap_inline's guard on `fn`. If we call wrap_inline on enough different functions, we would hit the recompile limit. cc voznesenskym penguinwu EikanWang jgong5 Guobing-Chen XiaobingSuper zhuhaozhe blzheng wenzhe-nrv jiayisunx chenyang78 kadeng chauhang amjames Lucaskabela [ghstack-poisoned]
…utils.wrap_inline" This will prevent recompilations (i.e. logs to TORCH_LOGS="recompiles") due to wrap_inline's guard on `fn`. If we call wrap_inline on enough different functions, we would hit the recompile limit. cc voznesenskym penguinwu EikanWang jgong5 Guobing-Chen XiaobingSuper zhuhaozhe blzheng wenzhe-nrv jiayisunx chenyang78 kadeng chauhang amjames Lucaskabela [ghstack-poisoned]
…utils.wrap_inline" This will prevent recompilations (i.e. logs to TORCH_LOGS="recompiles") due to wrap_inline's guard on `fn`. If we call wrap_inline on enough different functions, we would hit the recompile limit. cc voznesenskym penguinwu EikanWang jgong5 Guobing-Chen XiaobingSuper zhuhaozhe blzheng wenzhe-nrv jiayisunx chenyang78 kadeng chauhang amjames Lucaskabela [ghstack-poisoned]
…utils.wrap_inline" This will prevent recompilations (i.e. logs to TORCH_LOGS="recompiles") due to wrap_inline's guard on `fn`. If we call wrap_inline on enough different functions, we would hit the recompile limit. cc voznesenskym penguinwu EikanWang jgong5 Guobing-Chen XiaobingSuper zhuhaozhe blzheng wenzhe-nrv jiayisunx chenyang78 kadeng chauhang amjames Lucaskabela [ghstack-poisoned]
…utils.wrap_inline" This will prevent recompilations (i.e. logs to TORCH_LOGS="recompiles") due to wrap_inline's guard on `fn`. If we call wrap_inline on enough different functions, we would hit the recompile limit. cc voznesenskym penguinwu EikanWang jgong5 Guobing-Chen XiaobingSuper zhuhaozhe blzheng wenzhe-nrv jiayisunx chenyang78 kadeng chauhang amjames Lucaskabela [ghstack-poisoned]
…utils.wrap_inline" This will prevent recompilations (i.e. logs to TORCH_LOGS="recompiles") due to wrap_inline's guard on `fn`. If we call wrap_inline on enough different functions, we would hit the recompile limit. cc voznesenskym penguinwu EikanWang jgong5 Guobing-Chen XiaobingSuper zhuhaozhe blzheng wenzhe-nrv jiayisunx chenyang78 kadeng chauhang amjames Lucaskabela [ghstack-poisoned]
…utils.wrap_inline" This will prevent recompilations (i.e. logs to TORCH_LOGS="recompiles") due to wrap_inline's guard on `fn`. If we call wrap_inline on enough different functions, we would hit the recompile limit. cc voznesenskym penguinwu EikanWang jgong5 Guobing-Chen XiaobingSuper zhuhaozhe blzheng wenzhe-nrv jiayisunx chenyang78 kadeng chauhang amjames Lucaskabela [ghstack-poisoned]
…utils.wrap_inline" This will prevent recompilations (i.e. logs to TORCH_LOGS="recompiles") due to wrap_inline's guard on `fn`. If we call wrap_inline on enough different functions, we would hit the recompile limit. cc voznesenskym penguinwu EikanWang jgong5 Guobing-Chen XiaobingSuper zhuhaozhe blzheng wenzhe-nrv jiayisunx chenyang78 kadeng chauhang amjames Lucaskabela [ghstack-poisoned]
…utils.wrap_inline" This will prevent recompilations (i.e. logs to TORCH_LOGS="recompiles") due to wrap_inline's guard on `fn`. If we call wrap_inline on enough different functions, we would hit the recompile limit. cc voznesenskym penguinwu EikanWang jgong5 Guobing-Chen XiaobingSuper zhuhaozhe blzheng wenzhe-nrv jiayisunx chenyang78 kadeng chauhang amjames Lucaskabela [ghstack-poisoned]
…utils.wrap_inline" This will prevent recompilations (i.e. logs to TORCH_LOGS="recompiles") due to wrap_inline's guard on `fn`. If we call wrap_inline on enough different functions, we would hit the recompile limit. cc voznesenskym penguinwu EikanWang jgong5 Guobing-Chen XiaobingSuper zhuhaozhe blzheng wenzhe-nrv jiayisunx chenyang78 kadeng chauhang amjames Lucaskabela [ghstack-poisoned]
…utils.wrap_inline" This will prevent recompilations (i.e. logs to TORCH_LOGS="recompiles") due to wrap_inline's guard on `fn`. If we call wrap_inline on enough different functions, we would hit the recompile limit. cc voznesenskym penguinwu EikanWang jgong5 Guobing-Chen XiaobingSuper zhuhaozhe blzheng wenzhe-nrv jiayisunx chenyang78 kadeng chauhang amjames Lucaskabela [ghstack-poisoned]
…utils.wrap_inline" This will prevent recompilations (i.e. logs to TORCH_LOGS="recompiles") due to wrap_inline's guard on `fn`. If we call wrap_inline on enough different functions, we would hit the recompile limit. cc voznesenskym penguinwu EikanWang jgong5 Guobing-Chen XiaobingSuper zhuhaozhe blzheng wenzhe-nrv jiayisunx chenyang78 kadeng chauhang amjames Lucaskabela [ghstack-poisoned]
…utils.wrap_inline" This will prevent recompilations (i.e. logs to TORCH_LOGS="recompiles") due to wrap_inline's guard on `fn`. If we call wrap_inline on enough different functions, we would hit the recompile limit. cc voznesenskym penguinwu EikanWang jgong5 Guobing-Chen XiaobingSuper zhuhaozhe blzheng wenzhe-nrv jiayisunx chenyang78 kadeng chauhang amjames Lucaskabela [ghstack-poisoned]
…utils.wrap_inline" This will prevent recompilations (i.e. logs to TORCH_LOGS="recompiles") due to wrap_inline's guard on `fn`. If we call wrap_inline on enough different functions, we would hit the recompile limit. cc voznesenskym penguinwu EikanWang jgong5 Guobing-Chen XiaobingSuper zhuhaozhe blzheng wenzhe-nrv jiayisunx chenyang78 kadeng chauhang amjames Lucaskabela [ghstack-poisoned]
…utils.wrap_inline" This will prevent recompilations (i.e. logs to TORCH_LOGS="recompiles") due to wrap_inline's guard on `fn`. If we call wrap_inline on enough different functions, we would hit the recompile limit. cc voznesenskym penguinwu EikanWang jgong5 Guobing-Chen XiaobingSuper zhuhaozhe blzheng wenzhe-nrv jiayisunx chenyang78 kadeng chauhang amjames Lucaskabela [ghstack-poisoned]
…utils.wrap_inline" This will prevent recompilations (i.e. logs to TORCH_LOGS="recompiles") due to wrap_inline's guard on `fn`. If we call wrap_inline on enough different functions, we would hit the recompile limit. cc voznesenskym penguinwu EikanWang jgong5 Guobing-Chen XiaobingSuper zhuhaozhe blzheng wenzhe-nrv jiayisunx chenyang78 kadeng chauhang amjames Lucaskabela [ghstack-poisoned]
Stack from ghstack (oldest at bottom):
This will prevent recompilations (i.e. logs to TORCH_LOGS="recompiles") due to wrap_inline's guard on
fn. If we call wrap_inline on enough different functions, we would hit the recompile limit.cc @voznesenskym @penguinwu @EikanWang @jgong5 @Guobing-Chen @XiaobingSuper @zhuhaozhe @blzheng @wenzhe-nrv @jiayisunx @chenyang78 @kadeng @chauhang @amjames @Lucaskabela