functionalization bugfix: using owning type when unwrapping tensors#76125
functionalization bugfix: using owning type when unwrapping tensors#76125bdhirsh wants to merge 8 commits intogh/bdhirsh/213/basefrom
Conversation
[ghstack-poisoned]
🔗 Helpful links
💊 CI failures summary and remediationsAs of commit ebb412f (more details on the Dr. CI page): Expand to see more💚 💚 Looks good so far! There are no failures yet. 💚 💚 This comment was automatically generated by Dr. CI (expand for details).Please report bugs/suggestions to the (internal) Dr. CI Users group. |
| for (const auto i : c10::irange(functional_tensor.size())) { | ||
| commit_update(functional_tensor[i]); | ||
| } | ||
| } |
There was a problem hiding this comment.
These aren't strictly necessary for this PR, but I need them later (accidentally bundled them in this commit)
ezyang
left a comment
There was a problem hiding this comment.
the one off seems fine. keep an eye on it in the future
…g tensors" Addresses the comment here: #73441 (comment) When the functionalization pass unwraps tensor arguments, we need to make sure the thing that we unwrap into has an owning type - we can't blindly base the type off whatever types come from the operator's schema. This is basically just a problem for `at::TensorList` (non-owning) - we need to use an owning `std::vector<Tensor>` instead. @ezyang I wasn't sure how general of a fix to make. `translate()` already knows a bit about "expensive conversions" from non-owning to owning types. I couldn't think of a way to re-use that code without making some larger changes (like teaching `CType`'s about whether they're owning types), so I added a simple fix inside the functionalization codegen. Feedback totally welcome. Here's part of the old `cat` kernel: ``` at::Tensor & cat_out_out(c10::DispatchKeySet dispatchKeySet, at::TensorList tensors, int64_t dim, at::Tensor & out) { at::TensorList tensors_; if (at::functionalization::impl::isFunctionalTensor(tensors)) { at::functionalization::impl::sync(tensors); tensors_ = at::functionalization::impl::from_functional_tensor(tensors); } else { tensors_ = tensors; } .... } ``` And here's the new one (the temporary it creates is a vector) ``` at::Tensor & cat_out_out(c10::DispatchKeySet dispatchKeySet, at::TensorList tensors, int64_t dim, at::Tensor & out) { ::std::vector<at::Tensor> tensors_; if (at::functionalization::impl::isFunctionalTensor(tensors)) { at::functionalization::impl::sync(tensors); tensors_ = at::functionalization::impl::from_functional_tensor(tensors); } else { tensors_ = tensors; } ... } ``` [ghstack-poisoned]
…g tensors" Addresses the comment here: #73441 (comment) When the functionalization pass unwraps tensor arguments, we need to make sure the thing that we unwrap into has an owning type - we can't blindly base the type off whatever types come from the operator's schema. This is basically just a problem for `at::TensorList` (non-owning) - we need to use an owning `std::vector<Tensor>` instead. @ezyang I wasn't sure how general of a fix to make. `translate()` already knows a bit about "expensive conversions" from non-owning to owning types. I couldn't think of a way to re-use that code without making some larger changes (like teaching `CType`'s about whether they're owning types), so I added a simple fix inside the functionalization codegen. Feedback totally welcome. Here's part of the old `cat` kernel: ``` at::Tensor & cat_out_out(c10::DispatchKeySet dispatchKeySet, at::TensorList tensors, int64_t dim, at::Tensor & out) { at::TensorList tensors_; if (at::functionalization::impl::isFunctionalTensor(tensors)) { at::functionalization::impl::sync(tensors); tensors_ = at::functionalization::impl::from_functional_tensor(tensors); } else { tensors_ = tensors; } .... } ``` And here's the new one (the temporary it creates is a vector) ``` at::Tensor & cat_out_out(c10::DispatchKeySet dispatchKeySet, at::TensorList tensors, int64_t dim, at::Tensor & out) { ::std::vector<at::Tensor> tensors_; if (at::functionalization::impl::isFunctionalTensor(tensors)) { at::functionalization::impl::sync(tensors); tensors_ = at::functionalization::impl::from_functional_tensor(tensors); } else { tensors_ = tensors; } ... } ``` [ghstack-poisoned]
…g tensors" Addresses the comment here: #73441 (comment) When the functionalization pass unwraps tensor arguments, we need to make sure the thing that we unwrap into has an owning type - we can't blindly base the type off whatever types come from the operator's schema. This is basically just a problem for `at::TensorList` (non-owning) - we need to use an owning `std::vector<Tensor>` instead. @ezyang I wasn't sure how general of a fix to make. `translate()` already knows a bit about "expensive conversions" from non-owning to owning types. I couldn't think of a way to re-use that code without making some larger changes (like teaching `CType`'s about whether they're owning types), so I added a simple fix inside the functionalization codegen. Feedback totally welcome. Here's part of the old `cat` kernel: ``` at::Tensor & cat_out_out(c10::DispatchKeySet dispatchKeySet, at::TensorList tensors, int64_t dim, at::Tensor & out) { at::TensorList tensors_; if (at::functionalization::impl::isFunctionalTensor(tensors)) { at::functionalization::impl::sync(tensors); tensors_ = at::functionalization::impl::from_functional_tensor(tensors); } else { tensors_ = tensors; } .... } ``` And here's the new one (the temporary it creates is a vector) ``` at::Tensor & cat_out_out(c10::DispatchKeySet dispatchKeySet, at::TensorList tensors, int64_t dim, at::Tensor & out) { ::std::vector<at::Tensor> tensors_; if (at::functionalization::impl::isFunctionalTensor(tensors)) { at::functionalization::impl::sync(tensors); tensors_ = at::functionalization::impl::from_functional_tensor(tensors); } else { tensors_ = tensors; } ... } ``` [ghstack-poisoned]
…g tensors" Addresses the comment here: #73441 (comment) When the functionalization pass unwraps tensor arguments, we need to make sure the thing that we unwrap into has an owning type - we can't blindly base the type off whatever types come from the operator's schema. This is basically just a problem for `at::TensorList` (non-owning) - we need to use an owning `std::vector<Tensor>` instead. @ezyang I wasn't sure how general of a fix to make. `translate()` already knows a bit about "expensive conversions" from non-owning to owning types. I couldn't think of a way to re-use that code without making some larger changes (like teaching `CType`'s about whether they're owning types), so I added a simple fix inside the functionalization codegen. Feedback totally welcome. Here's part of the old `cat` kernel: ``` at::Tensor & cat_out_out(c10::DispatchKeySet dispatchKeySet, at::TensorList tensors, int64_t dim, at::Tensor & out) { at::TensorList tensors_; if (at::functionalization::impl::isFunctionalTensor(tensors)) { at::functionalization::impl::sync(tensors); tensors_ = at::functionalization::impl::from_functional_tensor(tensors); } else { tensors_ = tensors; } .... } ``` And here's the new one (the temporary it creates is a vector) ``` at::Tensor & cat_out_out(c10::DispatchKeySet dispatchKeySet, at::TensorList tensors, int64_t dim, at::Tensor & out) { ::std::vector<at::Tensor> tensors_; if (at::functionalization::impl::isFunctionalTensor(tensors)) { at::functionalization::impl::sync(tensors); tensors_ = at::functionalization::impl::from_functional_tensor(tensors); } else { tensors_ = tensors; } ... } ``` [ghstack-poisoned]
…g tensors" Addresses the comment here: #73441 (comment) This PR should also fix a bug with `at::cat.out` in functionalization, so I added a test for it. When the functionalization pass unwraps tensor arguments, we need to make sure the thing that we unwrap into has an owning type - we can't blindly base the type off whatever types come from the operator's schema. This is basically just a problem for `at::TensorList` (non-owning) - we need to use an owning `std::vector<Tensor>` instead. @ezyang I wasn't sure how general of a fix to make. `translate()` already knows a bit about "expensive conversions" from non-owning to owning types. I couldn't think of a way to re-use that code without making some larger changes (like teaching `CType`'s about whether they're owning types), so I added a simple fix inside the functionalization codegen. Feedback totally welcome. Here's part of the old `cat` kernel: ``` at::Tensor & cat_out_out(c10::DispatchKeySet dispatchKeySet, at::TensorList tensors, int64_t dim, at::Tensor & out) { at::TensorList tensors_; if (at::functionalization::impl::isFunctionalTensor(tensors)) { at::functionalization::impl::sync(tensors); tensors_ = at::functionalization::impl::from_functional_tensor(tensors); } else { tensors_ = tensors; } .... } ``` And here's the new one (the temporary it creates is a vector) ``` at::Tensor & cat_out_out(c10::DispatchKeySet dispatchKeySet, at::TensorList tensors, int64_t dim, at::Tensor & out) { ::std::vector<at::Tensor> tensors_; if (at::functionalization::impl::isFunctionalTensor(tensors)) { at::functionalization::impl::sync(tensors); tensors_ = at::functionalization::impl::from_functional_tensor(tensors); } else { tensors_ = tensors; } ... } ``` [ghstack-poisoned]
…g tensors" Addresses the comment here: #73441 (comment) This PR should also fix a bug with `at::cat.out` in functionalization, so I added a test for it. When the functionalization pass unwraps tensor arguments, we need to make sure the thing that we unwrap into has an owning type - we can't blindly base the type off whatever types come from the operator's schema. This is basically just a problem for `at::TensorList` (non-owning) - we need to use an owning `std::vector<Tensor>` instead. @ezyang I wasn't sure how general of a fix to make. `translate()` already knows a bit about "expensive conversions" from non-owning to owning types. I couldn't think of a way to re-use that code without making some larger changes (like teaching `CType`'s about whether they're owning types), so I added a simple fix inside the functionalization codegen. Feedback totally welcome. Here's part of the old `cat` kernel: ``` at::Tensor & cat_out_out(c10::DispatchKeySet dispatchKeySet, at::TensorList tensors, int64_t dim, at::Tensor & out) { at::TensorList tensors_; if (at::functionalization::impl::isFunctionalTensor(tensors)) { at::functionalization::impl::sync(tensors); tensors_ = at::functionalization::impl::from_functional_tensor(tensors); } else { tensors_ = tensors; } .... } ``` And here's the new one (the temporary it creates is a vector) ``` at::Tensor & cat_out_out(c10::DispatchKeySet dispatchKeySet, at::TensorList tensors, int64_t dim, at::Tensor & out) { ::std::vector<at::Tensor> tensors_; if (at::functionalization::impl::isFunctionalTensor(tensors)) { at::functionalization::impl::sync(tensors); tensors_ = at::functionalization::impl::from_functional_tensor(tensors); } else { tensors_ = tensors; } ... } ``` [ghstack-poisoned]
|
@pytorchbot merge this please |
|
Merge failed due to Command Raised by https://github.com/pytorch/pytorch/actions/runs/2223007110 |
|
@pytorchbot merge this please |
|
Merge failed due to Command Raised by https://github.com/pytorch/pytorch/actions/runs/2223067256 |
…g tensors" Addresses the comment here: #73441 (comment) This PR should also fix a bug with `at::cat.out` in functionalization, so I added a test for it. When the functionalization pass unwraps tensor arguments, we need to make sure the thing that we unwrap into has an owning type - we can't blindly base the type off whatever types come from the operator's schema. This is basically just a problem for `at::TensorList` (non-owning) - we need to use an owning `std::vector<Tensor>` instead. @ezyang I wasn't sure how general of a fix to make. `translate()` already knows a bit about "expensive conversions" from non-owning to owning types. I couldn't think of a way to re-use that code without making some larger changes (like teaching `CType`'s about whether they're owning types), so I added a simple fix inside the functionalization codegen. Feedback totally welcome. Here's part of the old `cat` kernel: ``` at::Tensor & cat_out_out(c10::DispatchKeySet dispatchKeySet, at::TensorList tensors, int64_t dim, at::Tensor & out) { at::TensorList tensors_; if (at::functionalization::impl::isFunctionalTensor(tensors)) { at::functionalization::impl::sync(tensors); tensors_ = at::functionalization::impl::from_functional_tensor(tensors); } else { tensors_ = tensors; } .... } ``` And here's the new one (the temporary it creates is a vector) ``` at::Tensor & cat_out_out(c10::DispatchKeySet dispatchKeySet, at::TensorList tensors, int64_t dim, at::Tensor & out) { ::std::vector<at::Tensor> tensors_; if (at::functionalization::impl::isFunctionalTensor(tensors)) { at::functionalization::impl::sync(tensors); tensors_ = at::functionalization::impl::from_functional_tensor(tensors); } else { tensors_ = tensors; } ... } ``` [ghstack-poisoned]
|
@pytorchbot merge this please |
|
Merge failed due to Refusing to merge as mandatory check Lint failed for rule superuser |
|
@pytorchbot merge this please |
|
Hey @bdhirsh. |
…76125) Summary: Pull Request resolved: #76125 Approved by: https://github.com/ezyang Test Plan: contbuild & OSS CI, see https://hud.pytorch.org/commit/pytorch/pytorch/640ce6bc9bbd25603c80651fd2be3f0045ea0d75 Reviewed By: osalpekar Differential Revision: D35938196 Pulled By: bdhirsh fbshipit-source-id: 1640a07e70f4036e42f12d657628e37848e26c35
Addresses the comment here: #73441 (comment)
This PR should also fix a bug with
at::cat.outin functionalization, so I added a test for it.When the functionalization pass unwraps tensor arguments, we need to make sure the thing that we unwrap into has an owning type - we can't blindly base the type off whatever types come from the operator's schema.
This is basically just a problem for
at::TensorList(non-owning) - we need to use an owningstd::vector<Tensor>instead.@ezyang I wasn't sure how general of a fix to make.
translate()already knows a bit about "expensive conversions" from non-owning to owning types. I couldn't think of a way to re-use that code without making some larger changes (like teachingCType's about whether they're owning types), so I added a simple fix inside the functionalization codegen. Feedback totally welcome.Here's part of the old
catkernel:And here's the new one (the temporary it creates is a vector)
Stack from ghstack: