[PyTorch] Replace cached thread_locals with stack allocation in AOTI - #112116
[PyTorch] Replace cached thread_locals with stack allocation in AOTI#112116swolchok wants to merge 27 commits into
Conversation
This changes cached thread_local tensors to stack-allocated buffers. Since we were incidentally caching output in a thread_local, I had to add manual thread_local caching of outputs, which I implemented by caching a buffer and a Tensor whose storage is that buffer and then just memcpying the result into the cached buffer every time. Ideally, memory planning would be able to identify allocations that are the backing storage for outputs, but this should be good enough in the absence of planning. Differential Revision: [D50416438](https://our.internmc.facebook.com/intern/diff/D50416438/) [ghstack-poisoned]
🔗 Helpful Links🧪 See artifacts and rendered test results at hud.pytorch.org/pr/112116
Note: Links to docs will display an error until the docs builds have been completed. ✅ No FailuresAs of commit 2b6c386 with merge base 2e6b809 ( This comment was automatically generated by Dr. CI and updates every 15 minutes. |
…on in AOTI" This changes cached thread_local tensors to stack-allocated buffers. Since we were incidentally caching output in a thread_local, I had to add manual thread_local caching of outputs, which I implemented by caching a buffer and a Tensor whose storage is that buffer and then just memcpying the result into the cached buffer every time. Ideally, memory planning would be able to identify allocations that are the backing storage for outputs, but this should be good enough in the absence of planning. Differential Revision: [D50416438](https://our.internmc.facebook.com/intern/diff/D50416438/) cc voznesenskym penguinwu EikanWang jgong5 Guobing-Chen XiaobingSuper zhuhaozhe blzheng wenzhe-nrv jiayisunx peterbell10 ipiszy yf225 chenyang78 kadeng muchulee8 aakhundov ColinPeppler [ghstack-poisoned]
|
LGTM overall. Left a minor comment. There are some test failures that might be related to this change? |
| self.expr_printer = pexpr | ||
| self.cached_thread_locals = set() | ||
| self.user_defined_kernel_count = 0 | ||
| self.allow_stack_allocation = None |
There was a problem hiding this comment.
Do we initialize allow_stack_allocation with None on purpose? If so, wondering what the difference would be between None and False for this flag.
There was a problem hiding this comment.
None is "not decided yet", False is "decided false"
the broken test is disabled in fbcode. I'll try a blind fix but if that doesn't work I have no way to debug it. |
…on in AOTI" This changes cached thread_local tensors to stack-allocated buffers. Since we were incidentally caching output in a thread_local, I had to add manual thread_local caching of outputs, which I implemented by caching a buffer and a Tensor whose storage is that buffer and then just memcpying the result into the cached buffer every time. Ideally, memory planning would be able to identify allocations that are the backing storage for outputs, but this should be good enough in the absence of planning. Differential Revision: [D50416438](https://our.internmc.facebook.com/intern/diff/D50416438/) cc voznesenskym penguinwu EikanWang jgong5 Guobing-Chen XiaobingSuper zhuhaozhe blzheng wenzhe-nrv jiayisunx peterbell10 ipiszy yf225 chenyang78 kadeng muchulee8 aakhundov ColinPeppler [ghstack-poisoned]
…on in AOTI" This changes cached thread_local tensors to stack-allocated buffers. Since we were incidentally caching output in a thread_local, I had to add manual thread_local caching of outputs, which I implemented by caching a buffer and a Tensor whose storage is that buffer and then just memcpying the result into the cached buffer every time. Ideally, memory planning would be able to identify allocations that are the backing storage for outputs, but this should be good enough in the absence of planning. Differential Revision: [D50416438](https://our.internmc.facebook.com/intern/diff/D50416438/) cc voznesenskym penguinwu EikanWang jgong5 Guobing-Chen XiaobingSuper zhuhaozhe blzheng wenzhe-nrv jiayisunx peterbell10 ipiszy yf225 chenyang78 kadeng muchulee8 aakhundov ColinPeppler [ghstack-poisoned]
…on in AOTI" This changes cached thread_local tensors to stack-allocated buffers. Since we were incidentally caching output in a thread_local, I had to add manual thread_local caching of outputs, which I implemented by caching a buffer and a Tensor whose storage is that buffer and then just memcpying the result into the cached buffer every time. Ideally, memory planning would be able to identify allocations that are the backing storage for outputs, but this should be good enough in the absence of planning. Differential Revision: [D50416438](https://our.internmc.facebook.com/intern/diff/D50416438/) cc voznesenskym penguinwu EikanWang jgong5 Guobing-Chen XiaobingSuper zhuhaozhe blzheng wenzhe-nrv jiayisunx peterbell10 ipiszy yf225 chenyang78 kadeng muchulee8 aakhundov ColinPeppler [ghstack-poisoned]
|
lintrunner failure is clearly not related to this diff |
…on in AOTI" This changes cached thread_local tensors to stack-allocated buffers. Since we were incidentally caching output in a thread_local, I had to add manual thread_local caching of outputs, which I implemented by caching a buffer and a Tensor whose storage is that buffer and then just memcpying the result into the cached buffer every time. Ideally, memory planning would be able to identify allocations that are the backing storage for outputs, but this should be good enough in the absence of planning. Differential Revision: [D50416438](https://our.internmc.facebook.com/intern/diff/D50416438/) cc voznesenskym penguinwu EikanWang jgong5 Guobing-Chen XiaobingSuper zhuhaozhe blzheng wenzhe-nrv jiayisunx peterbell10 ipiszy yf225 chenyang78 kadeng muchulee8 aakhundov ColinPeppler [ghstack-poisoned]
Pull Request resolved: #112116 This changes cached thread_local tensors to stack-allocated buffers. Since we were incidentally caching output in a thread_local, I had to add manual thread_local caching of outputs, which I implemented by caching a buffer and a Tensor whose storage is that buffer and then just memcpying the result into the cached buffer every time. Ideally, memory planning would be able to identify allocations that are the backing storage for outputs, but this should be good enough in the absence of planning. ghstack-source-id: 205864117 @exported-using-ghexport Differential Revision: [D50416438](https://our.internmc.facebook.com/intern/diff/D50416438/)
Lint failure looks related to me. |
desertfire
left a comment
There was a problem hiding this comment.
The coding LGTM. Left some minor comment. A more general concern I have is this adds more complexity to the wrapper codegen. With the memory planning PR #112178 merged (reverted with some ROCM test failures to be fixed/skiped), should we give that a try to see it is sufficient enough for your use case?
|
|
||
| static_shape = self.wrapper.static_shape_for_buffer_or_none(self.node) | ||
| if static_shape is not None: | ||
| state.total_allocated_buffer_size += int( |
There was a problem hiding this comment.
In a case where there are both CPU and GPU buffers, I think we are counting both, which is less ideal.
|
Also I left some comments in D50416438 for fixing lint issues. |
…112174) No need to populate a stack-based array for a shape/stride array when it's statically known. Differential Revision: [D50699889](https://our.internmc.facebook.com/intern/diff/D50699889/) Pull Request resolved: #112174 Approved by: https://github.com/chenyang78, https://github.com/desertfire, https://github.com/jansel ghstack dependencies: #112116
…rence time (#112405) Cache aoti_torch_get_data_ptr at constants update time. Differential Revision: [D50708982](https://our.internmc.facebook.com/intern/diff/D50708982/) Pull Request resolved: #112405 Approved by: https://github.com/chenyang78, https://github.com/desertfire, https://github.com/khabinov ghstack dependencies: #112116, #112174
dynamic_cast is for when we aren't certain about the type. We are certain (and will crash anyway if we're wrong). Differential Revision: [D50812978](https://our.internmc.facebook.com/intern/diff/D50812978/) Pull Request resolved: #112798 Approved by: https://github.com/chenyang78, https://github.com/desertfire, https://github.com/jansel, https://github.com/khabinov ghstack dependencies: #112116, #112174, #112405
Lot of simple information about tensors we couldn't get. In particular, we didn't know the lengths of the arrays returned by sizes and strides. Differential Revision: [D50949929](https://our.internmc.facebook.com/intern/diff/D50949929/) Pull Request resolved: #112799 Approved by: https://github.com/desertfire, https://github.com/aakhundov ghstack dependencies: #112116, #112174, #112405, #112798
Lot of simple information about tensors we couldn't get. In particular, we didn't know the lengths of the arrays returned by sizes and strides. Differential Revision: [D50949929](https://our.internmc.facebook.com/intern/diff/D50949929/) Pull Request resolved: #112799 Approved by: https://github.com/desertfire, https://github.com/aakhundov ghstack dependencies: #112116, #112174, #112405, #112798
…ytorch#112116) This changes cached thread_local tensors to stack-allocated buffers. Since we were incidentally caching output in a thread_local, I had to add manual thread_local caching of outputs, which I implemented by caching a buffer and a Tensor whose storage is that buffer and then just memcpying the result into the cached buffer every time. Ideally, memory planning would be able to identify allocations that are the backing storage for outputs, but this should be good enough in the absence of planning. Differential Revision: [D50416438](https://our.internmc.facebook.com/intern/diff/D50416438/) Pull Request resolved: pytorch#112116 Approved by: https://github.com/jansel, https://github.com/desertfire
…ytorch#112174) No need to populate a stack-based array for a shape/stride array when it's statically known. Differential Revision: [D50699889](https://our.internmc.facebook.com/intern/diff/D50699889/) Pull Request resolved: pytorch#112174 Approved by: https://github.com/chenyang78, https://github.com/desertfire, https://github.com/jansel ghstack dependencies: pytorch#112116
…rence time (pytorch#112405) Cache aoti_torch_get_data_ptr at constants update time. Differential Revision: [D50708982](https://our.internmc.facebook.com/intern/diff/D50708982/) Pull Request resolved: pytorch#112405 Approved by: https://github.com/chenyang78, https://github.com/desertfire, https://github.com/khabinov ghstack dependencies: pytorch#112116, pytorch#112174
dynamic_cast is for when we aren't certain about the type. We are certain (and will crash anyway if we're wrong). Differential Revision: [D50812978](https://our.internmc.facebook.com/intern/diff/D50812978/) Pull Request resolved: pytorch#112798 Approved by: https://github.com/chenyang78, https://github.com/desertfire, https://github.com/jansel, https://github.com/khabinov ghstack dependencies: pytorch#112116, pytorch#112174, pytorch#112405
Lot of simple information about tensors we couldn't get. In particular, we didn't know the lengths of the arrays returned by sizes and strides. Differential Revision: [D50949929](https://our.internmc.facebook.com/intern/diff/D50949929/) Pull Request resolved: pytorch#112799 Approved by: https://github.com/desertfire, https://github.com/aakhundov ghstack dependencies: pytorch#112116, pytorch#112174, pytorch#112405, pytorch#112798
Lot of simple information about tensors we couldn't get. In particular, we didn't know the lengths of the arrays returned by sizes and strides. Differential Revision: [D50949929](https://our.internmc.facebook.com/intern/diff/D50949929/) Pull Request resolved: pytorch#112799 Approved by: https://github.com/desertfire, https://github.com/aakhundov ghstack dependencies: pytorch#112116, pytorch#112174, pytorch#112405, pytorch#112798
…ytorch#112116) This changes cached thread_local tensors to stack-allocated buffers. Since we were incidentally caching output in a thread_local, I had to add manual thread_local caching of outputs, which I implemented by caching a buffer and a Tensor whose storage is that buffer and then just memcpying the result into the cached buffer every time. Ideally, memory planning would be able to identify allocations that are the backing storage for outputs, but this should be good enough in the absence of planning. Differential Revision: [D50416438](https://our.internmc.facebook.com/intern/diff/D50416438/) Pull Request resolved: pytorch#112116 Approved by: https://github.com/jansel, https://github.com/desertfire
…ytorch#112174) No need to populate a stack-based array for a shape/stride array when it's statically known. Differential Revision: [D50699889](https://our.internmc.facebook.com/intern/diff/D50699889/) Pull Request resolved: pytorch#112174 Approved by: https://github.com/chenyang78, https://github.com/desertfire, https://github.com/jansel ghstack dependencies: pytorch#112116
…rence time (pytorch#112405) Cache aoti_torch_get_data_ptr at constants update time. Differential Revision: [D50708982](https://our.internmc.facebook.com/intern/diff/D50708982/) Pull Request resolved: pytorch#112405 Approved by: https://github.com/chenyang78, https://github.com/desertfire, https://github.com/khabinov ghstack dependencies: pytorch#112116, pytorch#112174
dynamic_cast is for when we aren't certain about the type. We are certain (and will crash anyway if we're wrong). Differential Revision: [D50812978](https://our.internmc.facebook.com/intern/diff/D50812978/) Pull Request resolved: pytorch#112798 Approved by: https://github.com/chenyang78, https://github.com/desertfire, https://github.com/jansel, https://github.com/khabinov ghstack dependencies: pytorch#112116, pytorch#112174, pytorch#112405
Lot of simple information about tensors we couldn't get. In particular, we didn't know the lengths of the arrays returned by sizes and strides. Differential Revision: [D50949929](https://our.internmc.facebook.com/intern/diff/D50949929/) Pull Request resolved: pytorch#112799 Approved by: https://github.com/desertfire, https://github.com/aakhundov ghstack dependencies: pytorch#112116, pytorch#112174, pytorch#112405, pytorch#112798
Lot of simple information about tensors we couldn't get. In particular, we didn't know the lengths of the arrays returned by sizes and strides. Differential Revision: [D50949929](https://our.internmc.facebook.com/intern/diff/D50949929/) Pull Request resolved: pytorch#112799 Approved by: https://github.com/desertfire, https://github.com/aakhundov ghstack dependencies: pytorch#112116, pytorch#112174, pytorch#112405, pytorch#112798
Stack from ghstack (oldest at bottom):
This changes cached thread_local tensors to stack-allocated buffers. Since we were incidentally caching output in a thread_local, I had to add manual thread_local caching of outputs, which I implemented by caching a buffer and a Tensor whose storage is that buffer and then just memcpying the result into the cached buffer every time. Ideally, memory planning would be able to identify allocations that are the backing storage for outputs, but this should be good enough in the absence of planning.
Differential Revision: D50416438
cc @voznesenskym @penguinwu @EikanWang @jgong5 @Guobing-Chen @XiaobingSuper @zhuhaozhe @blzheng @wenzhe-nrv @jiayisunx @peterbell10 @ipiszy @yf225 @chenyang78 @kadeng @muchulee8 @aakhundov @ColinPeppler