Conversation
This adds a faithful API for ops with out arguments, as described in https://docs.google.com/document/d/1h7nBibRwkRLQ8rsPhfALlwWR0QbkdQm30u4ZBwmaps8/edit# . After this, an op will generate the following overloads for the C++ API: ```cpp // Generated from the aten::abs operator (NOT from aten::abs.out) Tensor at::abs(Tensor& self) // Generated from the aten::abs.out operator Tensor& at::abs(Tensor& self, Tensor& out) Tensor& at::abs_out(Tensor& out, Tensor& self) ``` This is an important step towards making those ops c10-full (it allows VariableType, XLA and other backends to ignore reordering and just call through with the same argument order), but this does not make any of those ops c10-full yet. It enables the faithful API independent from c10-fullness. That means the API is more consistent with the same API for all ops and making an op c10-full in the future will not trigger future C++ API changes. Differential Revision: [D24835252](https://our.internmc.facebook.com/intern/diff/D24835252/) [ghstack-poisoned]
This adds a faithful API for ops with out arguments, as described in https://docs.google.com/document/d/1h7nBibRwkRLQ8rsPhfALlwWR0QbkdQm30u4ZBwmaps8/edit# . After this, an op will generate the following overloads for the C++ API: ```cpp // Generated from the aten::abs operator (NOT from aten::abs.out) Tensor at::abs(Tensor& self) // Generated from the aten::abs.out operator Tensor& at::abs(Tensor& self, Tensor& out) Tensor& at::abs_out(Tensor& out, Tensor& self) ``` This is an important step towards making those ops c10-full (it allows VariableType, XLA and other backends to ignore reordering and just call through with the same argument order), but this does not make any of those ops c10-full yet. It enables the faithful API independent from c10-fullness. That means the API is more consistent with the same API for all ops and making an op c10-full in the future will not trigger future C++ API changes. Differential Revision: [D24835252](https://our.internmc.facebook.com/intern/diff/D24835252/) ghstack-source-id: 116359049 Pull Request resolved: #47712
💊 CI failures summary and remediationsAs of commit 24d4c01 (more details on the Dr. CI page): ✅ None of the CI failures appear to be your fault 💚
🚧 4 fixed upstream failures:These were probably caused by upstream breakages that were already fixed.
Please rebase on the
|
bhosmer
left a comment
There was a problem hiding this comment.
A few things I think we need to address here - interestingly they all have the same overall shape, moving new information into the data model and using it upstream, rather than adding free floating flag variables and using them downstream to tweak output :) happy to talk through any of these suggestions, not sure how much overlap there is between what I'm saying here and what you and @ezyang have talked about.
|
@smessmer Google docs are not visible to external people (because the FB gdocs org doesn't allow public sharing). You'll have to move it to your personal Google, or republish to https://github.com/pytorch/rfcs/ for accessibility |
|
Here's my new high level thinking about where we should be headed with the code generation here.
|
This adds a faithful API for ops with out arguments, as described in https://docs.google.com/document/d/1h7nBibRwkRLQ8rsPhfALlwWR0QbkdQm30u4ZBwmaps8/edit# . After this, an op will generate the following overloads for the C++ API: ```cpp // Generated from the aten::abs operator (NOT from aten::abs.out) Tensor at::abs(Tensor& self) // Generated from the aten::abs.out operator Tensor& at::abs(Tensor& self, Tensor& out) Tensor& at::abs_out(Tensor& out, Tensor& self) ``` This is an important step towards making those ops c10-full (it allows VariableType, XLA and other backends to ignore reordering and just call through with the same argument order), but this does not make any of those ops c10-full yet. It enables the faithful API independent from c10-fullness. That means the API is more consistent with the same API for all ops and making an op c10-full in the future will not trigger future C++ API changes. Differential Revision: [D24835252](https://our.internmc.facebook.com/intern/diff/D24835252/) [ghstack-poisoned]
This adds a faithful API for ops with out arguments, as described in https://docs.google.com/document/d/1h7nBibRwkRLQ8rsPhfALlwWR0QbkdQm30u4ZBwmaps8/edit# . After this, an op will generate the following overloads for the C++ API: ```cpp // Generated from the aten::abs operator (NOT from aten::abs.out) Tensor at::abs(Tensor& self) // Generated from the aten::abs.out operator Tensor& at::abs(Tensor& self, Tensor& out) Tensor& at::abs_out(Tensor& out, Tensor& self) ``` This is an important step towards making those ops c10-full (it allows VariableType, XLA and other backends to ignore reordering and just call through with the same argument order), but this does not make any of those ops c10-full yet. It enables the faithful API independent from c10-fullness. That means the API is more consistent with the same API for all ops and making an op c10-full in the future will not trigger future C++ API changes. Differential Revision: [D24835252](https://our.internmc.facebook.com/intern/diff/D24835252/) [ghstack-poisoned]
|
I reimplemented this PR on top of #48195. This makes it much better. PTAL |
This adds a faithful API for ops with out arguments, as described in https://docs.google.com/document/d/1h7nBibRwkRLQ8rsPhfALlwWR0QbkdQm30u4ZBwmaps8/edit# . After this, an op will generate the following overloads for the C++ API: ```cpp // Generated from the aten::abs operator (NOT from aten::abs.out) Tensor at::abs(Tensor& self) // Generated from the aten::abs.out operator Tensor& at::abs(Tensor& self, Tensor& out) Tensor& at::abs_out(Tensor& out, Tensor& self) ``` This is an important step towards making those ops c10-full (it allows VariableType, XLA and other backends to ignore reordering and just call through with the same argument order), but this does not make any of those ops c10-full yet. It enables the faithful API independent from c10-fullness. That means the API is more consistent with the same API for all ops and making an op c10-full in the future will not trigger future C++ API changes. Differential Revision: [D24835252](https://our.internmc.facebook.com/intern/diff/D24835252/) [ghstack-poisoned]
This adds a faithful API for ops with out arguments, as described in https://docs.google.com/document/d/1h7nBibRwkRLQ8rsPhfALlwWR0QbkdQm30u4ZBwmaps8/edit# . After this, an op will generate the following overloads for the C++ API: ```cpp // Generated from the aten::abs operator (NOT from aten::abs.out) Tensor at::abs(Tensor& self) // Generated from the aten::abs.out operator Tensor& at::abs(Tensor& self, Tensor& out) Tensor& at::abs_out(Tensor& out, Tensor& self) ``` This is an important step towards making those ops c10-full (it allows VariableType, XLA and other backends to ignore reordering and just call through with the same argument order), but this does not make any of those ops c10-full yet. It enables the faithful API independent from c10-fullness. That means the API is more consistent with the same API for all ops and making an op c10-full in the future will not trigger future C++ API changes. The old API is still around and valid, so backward compatibility is not broken there. However, this does break bc in an a bit more unexpected way (in the same way as adding a new operator overload always breaks bc). Concretely, the `Tensor::m(at::my_op, args...)` only works if `at::my_op` doesn't have multiple overloads. Previously, out overloads were excluded from that rule and an operator that had one regular and one out overload still worked. This does now not work anymore because out overloads behave more like regular overloads. Differential Revision: [D24835252](https://our.internmc.facebook.com/intern/diff/D24835252/) [ghstack-poisoned]
This adds a faithful API for ops with out arguments, as described in https://docs.google.com/document/d/1h7nBibRwkRLQ8rsPhfALlwWR0QbkdQm30u4ZBwmaps8/edit# . After this, an op will generate the following overloads for the C++ API: ```cpp // Generated from the aten::abs operator (NOT from aten::abs.out) Tensor at::abs(Tensor& self) // Generated from the aten::abs.out operator Tensor& at::abs(Tensor& self, Tensor& out) Tensor& at::abs_out(Tensor& out, Tensor& self) ``` This is an important step towards making those ops c10-full (it allows VariableType, XLA and other backends to ignore reordering and just call through with the same argument order), but this does not make any of those ops c10-full yet. It enables the faithful API independent from c10-fullness. That means the API is more consistent with the same API for all ops and making an op c10-full in the future will not trigger future C++ API changes. The old API is still around and valid, so backward compatibility is not broken there. However, this does break bc in an a bit more unexpected way (in the same way as adding a new operator overload always breaks bc). Concretely, the `Tensor::m(at::my_op, args...)` only works if `at::my_op` doesn't have multiple overloads. Previously, out overloads were excluded from that rule and an operator that had one regular and one out overload still worked. This does now not work anymore because out overloads behave more like regular overloads. This also breaks `torch::nn::Functional(at::sigmoid)` for those ops. Furthermore, this will break any third party code that uses `at::my_op` as a symbol to get its function pointer without specifying the full argument list. Those broken APIs, however, only worked for ops without overloads previously and adding any overload would have broken them. A workaround for users to still use those APIs is to explicitly specify the argument list like `torch::nn::Functional(static_cast<Tensor(*)(const Tensor&)>(at::sigmoid))`. But this is super ugly. We probably should reconsider those APIs and reimplement them differently. Differential Revision: [D24835252](https://our.internmc.facebook.com/intern/diff/D24835252/) [ghstack-poisoned]
Codecov Report
@@ Coverage Diff @@
## gh/smessmer/267/base #47712 +/- ##
========================================================
- Coverage 80.79% 80.79% -0.01%
========================================================
Files 1865 1865
Lines 201099 201099
========================================================
- Hits 162473 162469 -4
- Misses 38626 38630 +4 |
bhosmer
left a comment
There was a problem hiding this comment.
Some comments inline, I'll follow up 1-1 :)
ezyang
left a comment
There was a problem hiding this comment.
Still a bit nervous about m() and Functional(), but this seems good enough to go in.
bhosmer
left a comment
There was a problem hiding this comment.
Putting a changes requested to make sure we discuss the overloading issue (Functional() etc.), its possible downstream consequences and the cost of alternatives. Let's schedule a chat once you're settled.
The less consequential stuff (per earlier inline comments) we can potentially sort out post-PR, in conjunction with @ezyang's refactoring ideas.
This adds a faithful API for ops with out arguments, as described in https://docs.google.com/document/d/1h7nBibRwkRLQ8rsPhfALlwWR0QbkdQm30u4ZBwmaps8/edit# . After this, an op will generate the following overloads for the C++ API: ```cpp // Generated from the aten::abs operator (NOT from aten::abs.out) Tensor at::abs(Tensor& self) // Generated from the aten::abs.out operator Tensor& at::abs(Tensor& self, Tensor& out) Tensor& at::abs_out(Tensor& out, Tensor& self) ``` This is an important step towards making those ops c10-full (it allows VariableType, XLA and other backends to ignore reordering and just call through with the same argument order), but this does not make any of those ops c10-full yet. It enables the faithful API independent from c10-fullness. That means the API is more consistent with the same API for all ops and making an op c10-full in the future will not trigger future C++ API changes. The old API is still around and valid, so backward compatibility is not broken there. However, this does break bc in an a bit more unexpected way (in the same way as adding a new operator overload always breaks bc). Concretely, the `Tensor::m(at::my_op, args...)` only works if `at::my_op` doesn't have multiple overloads. Previously, out overloads were excluded from that rule and an operator that had one regular and one out overload still worked. This does now not work anymore because out overloads behave more like regular overloads. This also breaks `torch::nn::Functional(at::sigmoid)` for those ops. Furthermore, this will break any third party code that uses `at::my_op` as a symbol to get its function pointer without specifying the full argument list. Those broken APIs, however, only worked for ops without overloads previously and adding any overload would have broken them. A workaround for users to still use those APIs is to explicitly specify the argument list like `torch::nn::Functional(static_cast<Tensor(*)(const Tensor&)>(at::sigmoid))`. But this is super ugly. We probably should reconsider those APIs and reimplement them differently. Differential Revision: [D24835252](https://our.internmc.facebook.com/intern/diff/D24835252/) [ghstack-poisoned]
bhosmer
left a comment
There was a problem hiding this comment.
Cool - very happy to dodge the newly-overloaded ops risk.
- couple nits inline
- after this stack lands we should do a refactor based on Ed's "high level thinking" comment, which will ripple into here in a good way
- I'll add an H1 item for the struct-overload-bundle idea
This adds a faithful API for ops with out arguments, as described in https://docs.google.com/document/d/1h7nBibRwkRLQ8rsPhfALlwWR0QbkdQm30u4ZBwmaps8/edit# . After this, an op will generate the following overloads for the C++ API: ```cpp // Generated from the aten::abs operator (NOT from aten::abs.out) Tensor at::abs(Tensor& self) // Generated from the aten::abs.out operator Tensor& at::abs(Tensor& self, Tensor& out) Tensor& at::abs_out(Tensor& out, Tensor& self) ``` This is an important step towards making those ops c10-full (it allows VariableType, XLA and other backends to ignore reordering and just call through with the same argument order), but this does not make any of those ops c10-full yet. It enables the faithful API independent from c10-fullness. That means the API is more consistent with the same API for all ops and making an op c10-full in the future will not trigger future C++ API changes. The old API is still around and valid, so backward compatibility is not broken there. However, this does break bc in an a bit more unexpected way (in the same way as adding a new operator overload always breaks bc). Concretely, the `Tensor::m(at::my_op, args...)` only works if `at::my_op` doesn't have multiple overloads. Previously, out overloads were excluded from that rule and an operator that had one regular and one out overload still worked. This does now not work anymore because out overloads behave more like regular overloads. This also breaks `torch::nn::Functional(at::sigmoid)` for those ops. Furthermore, this will break any third party code that uses `at::my_op` as a symbol to get its function pointer without specifying the full argument list. Those broken APIs, however, only worked for ops without overloads previously and adding any overload would have broken them. A workaround for users to still use those APIs is to explicitly specify the argument list like `torch::nn::Functional(static_cast<Tensor(*)(const Tensor&)>(at::sigmoid))`. But this is super ugly. We probably should reconsider those APIs and reimplement them differently. **edit**: To avoid breaking the APIs, we decided to introduce `at::myop_outf` overloads instead that represent the faithful version of out overloads. This means we don't do the API cleanup yet that this was planning, but there's plans to do that down the road the right way. Differential Revision: [D24835252](https://our.internmc.facebook.com/intern/diff/D24835252/) [ghstack-poisoned]
This adds a faithful API for ops with out arguments, as described in https://docs.google.com/document/d/1h7nBibRwkRLQ8rsPhfALlwWR0QbkdQm30u4ZBwmaps8/edit# . After this, an op will generate the following overloads for the C++ API: ```cpp // Generated from the aten::abs operator (NOT from aten::abs.out) Tensor at::abs(Tensor& self) // Generated from the aten::abs.out operator Tensor& at::abs(Tensor& self, Tensor& out) Tensor& at::abs_out(Tensor& out, Tensor& self) ``` This is an important step towards making those ops c10-full (it allows VariableType, XLA and other backends to ignore reordering and just call through with the same argument order), but this does not make any of those ops c10-full yet. It enables the faithful API independent from c10-fullness. That means the API is more consistent with the same API for all ops and making an op c10-full in the future will not trigger future C++ API changes. The old API is still around and valid, so backward compatibility is not broken there. However, this does break bc in an a bit more unexpected way (in the same way as adding a new operator overload always breaks bc). Concretely, the `Tensor::m(at::my_op, args...)` only works if `at::my_op` doesn't have multiple overloads. Previously, out overloads were excluded from that rule and an operator that had one regular and one out overload still worked. This does now not work anymore because out overloads behave more like regular overloads. This also breaks `torch::nn::Functional(at::sigmoid)` for those ops. Furthermore, this will break any third party code that uses `at::my_op` as a symbol to get its function pointer without specifying the full argument list. Those broken APIs, however, only worked for ops without overloads previously and adding any overload would have broken them. A workaround for users to still use those APIs is to explicitly specify the argument list like `torch::nn::Functional(static_cast<Tensor(*)(const Tensor&)>(at::sigmoid))`. But this is super ugly. We probably should reconsider those APIs and reimplement them differently. **edit**: To avoid breaking the APIs, we decided to introduce `at::myop_outf` overloads instead that represent the faithful version of out overloads. This means we don't do the API cleanup yet that this was planning, but there's plans to do that down the road the right way. Differential Revision: [D24835252](https://our.internmc.facebook.com/intern/diff/D24835252/) [ghstack-poisoned]
|
This pull request has been merged in 3ef36dc. |
Stack from ghstack:
This adds a faithful API for ops with out arguments, as described in https://docs.google.com/document/d/1h7nBibRwkRLQ8rsPhfALlwWR0QbkdQm30u4ZBwmaps8/edit# .
After this, an op will generate the following overloads for the C++ API:
This is an important step towards making those ops c10-full (it allows VariableType, XLA and other backends to ignore reordering and just call through with the same argument order), but this does not make any of those ops c10-full yet.
It enables the faithful API independent from c10-fullness. That means the API is more consistent with the same API for all ops and making an op c10-full in the future will not trigger future C++ API changes.
The old API is still around and valid, so backward compatibility is not broken there.
However, this does break bc in an a bit more unexpected way (in the same way as adding a new operator overload always breaks bc). Concretely, the
Tensor::m(at::my_op, args...)only works ifat::my_opdoesn't have multiple overloads. Previously, out overloads were excluded from that rule and an operator that had one regular and one out overload still worked. This does now not work anymore because out overloads behave more like regular overloads. This also breakstorch::nn::Functional(at::sigmoid)for those ops. Furthermore, this will break any third party code that usesat::my_opas a symbol to get its function pointer without specifying the full argument list.Those broken APIs, however, only worked for ops without overloads previously and adding any overload would have broken them. A workaround for users to still use those APIs is to explicitly specify the argument list like
torch::nn::Functional(static_cast<Tensor(*)(const Tensor&)>(at::sigmoid)). But this is super ugly.We probably should reconsider those APIs and reimplement them differently.
edit: To avoid breaking the APIs, we decided to introduce
at::myop_outfoverloads instead that represent the faithful version of out overloads. This means we don't do the API cleanup yet that this was planning, but there's plans to do that down the road the right way.Differential Revision: D24835252