add a new alias key for functional to non functional decompositions#76358
add a new alias key for functional to non functional decompositions#76358bdhirsh wants to merge 40 commits intogh/bdhirsh/220/basefrom
Conversation
[ghstack-poisoned]
🔗 Helpful links
❌ 2 New FailuresAs of commit 0778a55 (more details on the Dr. CI page): Expand to see more
🕵️ 2 new failures recognized by patternsThe following CI failures do not appear to be due to upstream breakages
|
…itions" [ghstack-poisoned]
…itions" [ghstack-poisoned]
…itions" [ghstack-poisoned]
|
@bdhirsh has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator. |
| // (3) Use fallthrough kernel that are registered as fallback. | ||
| // Alias Key Precedence: | ||
| // CompositeExplicitAutograd > CompositeImplicitAutograd > Autograd | ||
| // CompositExplicitAutogradWithMutations > CompositeExplicitAutograd > CompositeImplicitAutograd > Autograd |
There was a problem hiding this comment.
I figured that the CompositeExplicitAutogradWithMutations kernels should get higher precedence, since they belong to a more specific group of dispatch keys than CompositeExplicitAutograd
There was a problem hiding this comment.
I don't follow. I could have renamed these CompositeExplicitAutograd and CompositeExplicitAutogradWithoutMutations and it seems to me like the latter is more specific!
There was a problem hiding this comment.
I meant more specific in terms of "the number of dispatch keys in the alias set". size(CompositeExplicitAutogradWithMutations) < size(CompositExplicitAutograd) < size(CompositeImplicitAutograd).
I guess this also shouldn't matter too much in practice, since we shouldn't really ever have an op that has both a CompositExplicitAutogradWithMutations and a CompositExplicitAutograd kernel.
| "functions, they will be automatically generated for you" | ||
| ) | ||
| elif self.backend_index.dispatch_key == DispatchKey.CompositeExplicitAutograd: | ||
| elif self.backend_index.dispatch_key == DispatchKey.CompositeExplicitAutogradWithMutations: |
There was a problem hiding this comment.
All of the codegen logic for generating functional -> out= kernels should now be registered to the new key.
I mentioned this in the PR description - I guess technically it would be more correct to register the functional kernels to the CompositeExplicitAutogradWithMutations key, and the inplace kernels to the CompositeExplicitAutograd key, but it seems harmless to register them both to the new key.
| structured_delegate: atanh.out | ||
| variants: function, method | ||
| dispatch: | ||
| CompositeExplicitAutograd: atanh |
There was a problem hiding this comment.
A bunch of these dispatch entries actually shouldn't be here, since they get generated automatically. It just didn't matter until now because they were shadowed by the codegen.
…itions"
This PR adds a new alias key for composite kernels, bringing the total count to 3. Composite kernels should be registered to this new key under the following conditions:
- The operator itself is functional (no alias annotations)
- The decomposition calls into ops that *do* have alias annotations (either mutations or views)
- The operator has a derivative formula
Current key name in the PR is `CompositeExplicitAutogradWithMutations`, but I'm open to any better ideas on the name for the new key - I guess I could also use this opportunity to rename the existing composite alias keys if we think it's really worth it, although I was hoping to not have to change the existing key names :)
This alias key is similar to the `CompositeExplicitAutograd` alias key, except that the `Lazy` and `XLA` runtime keys aren't included in it (and any other future "functional" backends). That's because functional -> non-functional decompositions are not useful / kinda bad for functional backends, especially once they start using the functionalization pass (at best they introduce unnecessary overhead, at worst they can potentially cause an infinite loop with the functionalization pass).
Other ideas:
- `CompositeExplicitAutogradNonFunctional` (better captures the fact that functional -> view decomps are also used here)
- `CompositeExplicitAutogradFunctionalToNonFunctional` (better captures the fact that the op itself should be functional, although probably way too wordy)
Note 1: in theory we could add a corresponding `CompositeImplicitAutogradWithMutations` key, but there isn't really a use case for it - it doesn't matter for functionalization, because `CompositeImplicitAutograd` kernels will *always* decompose before entering the functionalization pass.
Note 2: I was a little conflicted about what to do with mutation -> mutation decompositions (like an inplace op that decomposes to its out= variant). Semantically, I don't think it really makes sense for them to go in this key, because it doesn't matter if functional backends run them (it's only bad to *replace* a functional op with a non-functional one). We have a bunch of codegen'd `functional -> out=` and `inplace -> out=` kernels though, which I updated to get registered to the new `CompositeExplicitAutogradWithMutations` key. The `functional -> out=` kernels should definitely get registered to this key, but the `inplace -> out=` kernels probably shouldn't. But it's kind of harmless to register `inplace -> out=` kernels to the new key, and teasing that out would require adding a bunch of extra logic.
A good example of a kernel that fits this category is the `cummax` kernel, which looks like this (and cummax has a derivative formula defined):
```
std::tuple<Tensor, Tensor> cummax(const Tensor& self, int64_t dim) {
auto values = at::empty(self.sizes(), self.options());
auto indices = at::empty(self.sizes(), self.options().dtype(at::kLong));
at::cummax_out(values, indices, self, dim);
return std::make_tuple(values, indices);
}
```
**Have all of the relevant kernels been switched over to the new key in this PR?**
No. The only ones I switched were:
- all of the codegen'd kernels
- all of the (recently added) `view_copy.out` kernels in native_functions.yaml
- A handful of one-off kernels that I noticed in native_functions.yaml
But there are probably a bunch more - I'm going to switch more over as part of integrating functionalization with LTC/XLA.
Differential Revision: [D35953393](https://our.internmc.facebook.com/intern/diff/D35953393)
[ghstack-poisoned]
|
@bdhirsh has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator. |
| LazyTensor + XLA are the two current examples of this - since they operate on a functional IR, | ||
| they would prefer to directly implement an out-of-place operator with their own kernel, | ||
| instead of using a decomposition that results in more mutation operators. | ||
|
|
There was a problem hiding this comment.
I'm looking at the description here and feeling that this is all very complicated. I know I was the one who suggested composite with mutations in the first place (and though I have forgotten what more complicated solution we were replacing with this), and I think we should still put this PR in, but we should keep our eye out for a more general approach to this problem. Maybe the stuff on decompositions and primtorch feeds in here. cc @Chillee @mruberry
|
|
||
| assert len(composites_in_dispatch) <= 1, ( | ||
| "cannot specify more than one of CompositeExplicitAutograd, CompositeExplicitAutogradWithMutations, " | ||
| "or CompositeImplicitAutograd on a single kernel; each " |
There was a problem hiding this comment.
I don't think this is right. I could have both CompositeExplicitAutograd and CompositeExplicitAutogradWithMutations, and under the precedence you have currently implemented this would not be a no-op because CompositeExplicitAutogradWithMutations would be applied to all the non-functional backends and CompositeExplicitAutograd would be applied to the functional backends. This might even be useful if you prefer the mutating composite in eager mode.
There was a problem hiding this comment.
Oh, that's a good point (although I'm thinking of renaming this key to something like CompositeExplicitAutogradNonFunctional, since technically views are the main "problematic" ops, although mutations are technically problematic too, xla/ltc are just able to handle them more easily). Ok, it seems reasonable to allow for an operator to provide kernels for both keys.
…itions"
This PR adds a new alias key for composite kernels, bringing the total count to 3. Composite kernels should be registered to this new key under the following conditions:
- The operator itself is functional (no alias annotations)
- The decomposition calls into ops that *do* have alias annotations (either mutations or views)
- The operator has a derivative formula
This alias key is similar to the `CompositeExplicitAutograd` alias key, except that the `Lazy` and `XLA` runtime keys aren't included in it (and any other future "functional" backends). That's because functional -> non-functional decompositions are not useful / kinda bad for functional backends, especially once they start using the functionalization pass (at best they introduce unnecessary overhead, at worst they can potentially cause an infinite loop with the functionalization pass).
Current key name in the PR is `CompositeExplicitAutogradWithMutations`, but I'm open to any better ideas on the name for the new key - I guess I could also use this opportunity to rename the existing composite alias keys if we think it's really worth it, although I was hoping to not have to change the existing key names :)
Other ideas:
- `CompositeExplicitAutogradNonFunctional` (better captures the fact that functional -> view decomps are also used here)
- `CompositeExplicitAutogradFunctionalToNonFunctional` (better captures the fact that the op itself should be functional, although probably way too wordy)
Note 1: in theory we could add a corresponding `CompositeImplicitAutogradWithMutations` key, but there isn't really a use case for it - it doesn't matter for functionalization, because `CompositeImplicitAutograd` kernels will *always* decompose before entering the functionalization pass.
Note 2: I was a little conflicted about what to do with mutation -> mutation decompositions (like an inplace op that decomposes to its out= variant). Semantically, I don't think it really makes sense for them to go in this key, because it doesn't matter if functional backends run them (it's only bad to *replace* a functional op with a non-functional one). We have a bunch of codegen'd `functional -> out=` and `inplace -> out=` kernels though, which I updated to get registered to the new `CompositeExplicitAutogradWithMutations` key. The `functional -> out=` kernels should definitely get registered to this key, but the `inplace -> out=` kernels probably shouldn't. But it's kind of harmless to register `inplace -> out=` kernels to the new key, and teasing that out would require adding a bunch of extra logic.
A good example of a kernel that fits this category is the `cummax` kernel, which looks like this (and cummax has a derivative formula defined):
```
std::tuple<Tensor, Tensor> cummax(const Tensor& self, int64_t dim) {
auto values = at::empty(self.sizes(), self.options());
auto indices = at::empty(self.sizes(), self.options().dtype(at::kLong));
at::cummax_out(values, indices, self, dim);
return std::make_tuple(values, indices);
}
```
**Have all of the relevant kernels been switched over to the new key in this PR?**
No. The only ones I switched were:
- all of the codegen'd kernels
- all of the (recently added) `view_copy.out` kernels in native_functions.yaml
- A handful of one-off kernels that I noticed in native_functions.yaml
But there are probably a bunch more - I'm going to switch more over as part of integrating functionalization with LTC/XLA.
Differential Revision: [D35953393](https://our.internmc.facebook.com/intern/diff/D35953393)
[ghstack-poisoned]
…itions"
This PR adds a new alias key for composite kernels, bringing the total count to 3. Composite kernels should be registered to this new key under the following conditions:
- The operator itself is functional (no alias annotations)
- The decomposition calls into ops that *do* have alias annotations (either mutations or views)
- The operator has a derivative formula
This alias key is similar to the `CompositeExplicitAutograd` alias key, except that the `Lazy` and `XLA` runtime keys aren't included in it (and any other future "functional" backends). That's because functional -> non-functional decompositions are not useful / kinda bad for functional backends, especially once they start using the functionalization pass (at best they introduce unnecessary overhead, at worst they can potentially cause an infinite loop with the functionalization pass).
Current key name in the PR is `CompositeExplicitAutogradWithMutations`, but I'm open to any better ideas on the name for the new key - I guess I could also use this opportunity to rename the existing composite alias keys if we think it's really worth it, although I was hoping to not have to change the existing key names :)
Other ideas:
- `CompositeExplicitAutogradNonFunctional` (better captures the fact that functional -> view decomps are also used here)
- `CompositeExplicitAutogradFunctionalToNonFunctional` (better captures the fact that the op itself should be functional, although probably way too wordy)
Note 1: in theory we could add a corresponding `CompositeImplicitAutogradWithMutations` key, but there isn't really a use case for it - it doesn't matter for functionalization, because `CompositeImplicitAutograd` kernels will *always* decompose before entering the functionalization pass.
Note 2: I was a little conflicted about what to do with mutation -> mutation decompositions (like an inplace op that decomposes to its out= variant). Semantically, I don't think it really makes sense for them to go in this key, because it doesn't matter if functional backends run them (it's only bad to *replace* a functional op with a non-functional one). We have a bunch of codegen'd `functional -> out=` and `inplace -> out=` kernels though, which I updated to get registered to the new `CompositeExplicitAutogradWithMutations` key. The `functional -> out=` kernels should definitely get registered to this key, but the `inplace -> out=` kernels probably shouldn't. But it's kind of harmless to register `inplace -> out=` kernels to the new key, and teasing that out would require adding a bunch of extra logic.
A good example of a kernel that fits this category is the `cummax` kernel, which looks like this (and cummax has a derivative formula defined):
```
std::tuple<Tensor, Tensor> cummax(const Tensor& self, int64_t dim) {
auto values = at::empty(self.sizes(), self.options());
auto indices = at::empty(self.sizes(), self.options().dtype(at::kLong));
at::cummax_out(values, indices, self, dim);
return std::make_tuple(values, indices);
}
```
**Have all of the relevant kernels been switched over to the new key in this PR?**
No. The only ones I switched were:
- all of the codegen'd kernels
- all of the (recently added) `view_copy.out` kernels in native_functions.yaml
- A handful of one-off kernels that I noticed in native_functions.yaml
But there are probably a bunch more - I'm going to switch more over as part of integrating functionalization with LTC/XLA.
Differential Revision: [D35953393](https://our.internmc.facebook.com/intern/diff/D35953393)
[ghstack-poisoned]
…itions"
This PR adds a new alias key for composite kernels, bringing the total count to 3. Composite kernels should be registered to this new key under the following conditions:
- The operator itself is functional (no alias annotations)
- The decomposition calls into ops that *do* have alias annotations (either mutations or views)
- The operator has a derivative formula
This alias key is similar to the `CompositeExplicitAutograd` alias key, except that the `Lazy` and `XLA` runtime keys aren't included in it (and any other future "functional" backends). That's because functional -> non-functional decompositions are not useful / kinda bad for functional backends, especially once they start using the functionalization pass (at best they introduce unnecessary overhead, at worst they can potentially cause an infinite loop with the functionalization pass).
Current key name in the PR is `CompositeExplicitAutogradWithMutations`, but I'm open to any better ideas on the name for the new key - I guess I could also use this opportunity to rename the existing composite alias keys if we think it's really worth it, although I was hoping to not have to change the existing key names :)
Other ideas:
- `CompositeExplicitAutogradNonFunctional` (better captures the fact that functional -> view decomps are also used here)
- `CompositeExplicitAutogradFunctionalToNonFunctional` (better captures the fact that the op itself should be functional, although probably way too wordy)
Note 1: in theory we could add a corresponding `CompositeImplicitAutogradWithMutations` key, but there isn't really a use case for it - it doesn't matter for functionalization, because `CompositeImplicitAutograd` kernels will *always* decompose before entering the functionalization pass.
Note 2: I was a little conflicted about what to do with mutation -> mutation decompositions (like an inplace op that decomposes to its out= variant). Semantically, I don't think it really makes sense for them to go in this key, because it doesn't matter if functional backends run them (it's only bad to *replace* a functional op with a non-functional one). We have a bunch of codegen'd `functional -> out=` and `inplace -> out=` kernels though, which I updated to get registered to the new `CompositeExplicitAutogradWithMutations` key. The `functional -> out=` kernels should definitely get registered to this key, but the `inplace -> out=` kernels probably shouldn't. But it's kind of harmless to register `inplace -> out=` kernels to the new key, and teasing that out would require adding a bunch of extra logic.
A good example of a kernel that fits this category is the `cummax` kernel, which looks like this (and cummax has a derivative formula defined):
```
std::tuple<Tensor, Tensor> cummax(const Tensor& self, int64_t dim) {
auto values = at::empty(self.sizes(), self.options());
auto indices = at::empty(self.sizes(), self.options().dtype(at::kLong));
at::cummax_out(values, indices, self, dim);
return std::make_tuple(values, indices);
}
```
**Have all of the relevant kernels been switched over to the new key in this PR?**
No. The only ones I switched were:
- all of the codegen'd kernels
- all of the (recently added) `view_copy.out` kernels in native_functions.yaml
- A handful of one-off kernels that I noticed in native_functions.yaml
But there are probably a bunch more - I'm going to switch more over as part of integrating functionalization with LTC/XLA.
Differential Revision: [D35953393](https://our.internmc.facebook.com/intern/diff/D35953393)
[ghstack-poisoned]
…itions"
This PR adds a new alias key for composite kernels, bringing the total count to 3. Composite kernels should be registered to this new key under the following conditions:
- The operator itself is functional (no alias annotations)
- The decomposition calls into ops that *do* have alias annotations (either mutations or views)
- The operator has a derivative formula
This alias key is similar to the `CompositeExplicitAutograd` alias key, except that the `Lazy` and `XLA` runtime keys aren't included in it (and any other future "functional" backends). That's because functional -> non-functional decompositions are not useful / kinda bad for functional backends, especially once they start using the functionalization pass (at best they introduce unnecessary overhead, at worst they can potentially cause an infinite loop with the functionalization pass).
Current key name in the PR is `CompositeExplicitAutogradWithMutations`, but I'm open to any better ideas on the name for the new key - I guess I could also use this opportunity to rename the existing composite alias keys if we think it's really worth it, although I was hoping to not have to change the existing key names :)
Other ideas:
- `CompositeExplicitAutogradNonFunctional` (better captures the fact that functional -> view decomps are also used here)
- `CompositeExplicitAutogradFunctionalToNonFunctional` (better captures the fact that the op itself should be functional, although probably way too wordy)
Note 1: in theory we could add a corresponding `CompositeImplicitAutogradWithMutations` key, but there isn't really a use case for it - it doesn't matter for functionalization, because `CompositeImplicitAutograd` kernels will *always* decompose before entering the functionalization pass.
Note 2: I was a little conflicted about what to do with mutation -> mutation decompositions (like an inplace op that decomposes to its out= variant). Semantically, I don't think it really makes sense for them to go in this key, because it doesn't matter if functional backends run them (it's only bad to *replace* a functional op with a non-functional one). We have a bunch of codegen'd `functional -> out=` and `inplace -> out=` kernels though, which I updated to get registered to the new `CompositeExplicitAutogradWithMutations` key. The `functional -> out=` kernels should definitely get registered to this key, but the `inplace -> out=` kernels probably shouldn't. But it's kind of harmless to register `inplace -> out=` kernels to the new key, and teasing that out would require adding a bunch of extra logic.
A good example of a kernel that fits this category is the `cummax` kernel, which looks like this (and cummax has a derivative formula defined):
```
std::tuple<Tensor, Tensor> cummax(const Tensor& self, int64_t dim) {
auto values = at::empty(self.sizes(), self.options());
auto indices = at::empty(self.sizes(), self.options().dtype(at::kLong));
at::cummax_out(values, indices, self, dim);
return std::make_tuple(values, indices);
}
```
**Have all of the relevant kernels been switched over to the new key in this PR?**
No. The only ones I switched were:
- all of the codegen'd kernels
- all of the (recently added) `view_copy.out` kernels in native_functions.yaml
- A handful of one-off kernels that I noticed in native_functions.yaml
But there are probably a bunch more - I'm going to switch more over as part of integrating functionalization with LTC/XLA.
Differential Revision: [D35953393](https://our.internmc.facebook.com/intern/diff/D35953393)
[ghstack-poisoned]
|
@bdhirsh has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator. |
…itions"
This PR adds a new alias key for composite kernels, bringing the total count to 3. Composite kernels should be registered to this new key under the following conditions:
- The operator itself is functional (no alias annotations)
- The decomposition calls into ops that *do* have alias annotations (either mutations or views)
- The operator has a derivative formula
This alias key is similar to the `CompositeExplicitAutograd` alias key, except that the `Lazy` and `XLA` runtime keys aren't included in it (and any other future "functional" backends). That's because functional -> non-functional decompositions are not useful / kinda bad for functional backends, especially once they start using the functionalization pass (at best they introduce unnecessary overhead, at worst they can potentially cause an infinite loop with the functionalization pass).
Current key name in the PR is `CompositeExplicitAutogradWithMutations`, but I'm open to any better ideas on the name for the new key - I guess I could also use this opportunity to rename the existing composite alias keys if we think it's really worth it, although I was hoping to not have to change the existing key names :)
Other ideas:
- `CompositeExplicitAutogradNonFunctional` (better captures the fact that functional -> view decomps are also used here)
- `CompositeExplicitAutogradFunctionalToNonFunctional` (better captures the fact that the op itself should be functional, although probably way too wordy)
Note 1: in theory we could add a corresponding `CompositeImplicitAutogradWithMutations` key, but there isn't really a use case for it - it doesn't matter for functionalization, because `CompositeImplicitAutograd` kernels will *always* decompose before entering the functionalization pass.
Note 2: I was a little conflicted about what to do with mutation -> mutation decompositions (like an inplace op that decomposes to its out= variant). Semantically, I don't think it really makes sense for them to go in this key, because it doesn't matter if functional backends run them (it's only bad to *replace* a functional op with a non-functional one). We have a bunch of codegen'd `functional -> out=` and `inplace -> out=` kernels though, which I updated to get registered to the new `CompositeExplicitAutogradWithMutations` key. The `functional -> out=` kernels should definitely get registered to this key, but the `inplace -> out=` kernels probably shouldn't. But it's kind of harmless to register `inplace -> out=` kernels to the new key, and teasing that out would require adding a bunch of extra logic.
A good example of a kernel that fits this category is the `cummax` kernel, which looks like this (and cummax has a derivative formula defined):
```
std::tuple<Tensor, Tensor> cummax(const Tensor& self, int64_t dim) {
auto values = at::empty(self.sizes(), self.options());
auto indices = at::empty(self.sizes(), self.options().dtype(at::kLong));
at::cummax_out(values, indices, self, dim);
return std::make_tuple(values, indices);
}
```
**Have all of the relevant kernels been switched over to the new key in this PR?**
No. The only ones I switched were:
- all of the codegen'd kernels
- all of the (recently added) `view_copy.out` kernels in native_functions.yaml
- A handful of one-off kernels that I noticed in native_functions.yaml
But there are probably a bunch more - I'm going to switch more over as part of integrating functionalization with LTC/XLA.
Differential Revision: [D35953393](https://our.internmc.facebook.com/intern/diff/D35953393)
[ghstack-poisoned]
|
@bdhirsh has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator. |
…itions"
This PR adds a new alias key for composite kernels, bringing the total count to 3. Composite kernels should be registered to this new key under the following conditions:
- The operator itself is functional (no alias annotations)
- The decomposition calls into ops that *do* have alias annotations (either mutations or views)
- The operator has a derivative formula
This alias key is similar to the `CompositeExplicitAutograd` alias key, except that the `Lazy` and `XLA` runtime keys aren't included in it (and any other future "functional" backends). That's because functional -> non-functional decompositions are not useful / kinda bad for functional backends, especially once they start using the functionalization pass (at best they introduce unnecessary overhead, at worst they can potentially cause an infinite loop with the functionalization pass).
Current key name in the PR is `CompositeExplicitAutogradWithMutations`, but I'm open to any better ideas on the name for the new key - I guess I could also use this opportunity to rename the existing composite alias keys if we think it's really worth it, although I was hoping to not have to change the existing key names :)
Other ideas:
- `CompositeExplicitAutogradNonFunctional` (better captures the fact that functional -> view decomps are also used here)
- `CompositeExplicitAutogradFunctionalToNonFunctional` (better captures the fact that the op itself should be functional, although probably way too wordy)
Note 1: in theory we could add a corresponding `CompositeImplicitAutogradWithMutations` key, but there isn't really a use case for it - it doesn't matter for functionalization, because `CompositeImplicitAutograd` kernels will *always* decompose before entering the functionalization pass.
Note 2: I was a little conflicted about what to do with mutation -> mutation decompositions (like an inplace op that decomposes to its out= variant). Semantically, I don't think it really makes sense for them to go in this key, because it doesn't matter if functional backends run them (it's only bad to *replace* a functional op with a non-functional one). We have a bunch of codegen'd `functional -> out=` and `inplace -> out=` kernels though, which I updated to get registered to the new `CompositeExplicitAutogradWithMutations` key. The `functional -> out=` kernels should definitely get registered to this key, but the `inplace -> out=` kernels probably shouldn't. But it's kind of harmless to register `inplace -> out=` kernels to the new key, and teasing that out would require adding a bunch of extra logic.
A good example of a kernel that fits this category is the `cummax` kernel, which looks like this (and cummax has a derivative formula defined):
```
std::tuple<Tensor, Tensor> cummax(const Tensor& self, int64_t dim) {
auto values = at::empty(self.sizes(), self.options());
auto indices = at::empty(self.sizes(), self.options().dtype(at::kLong));
at::cummax_out(values, indices, self, dim);
return std::make_tuple(values, indices);
}
```
**Have all of the relevant kernels been switched over to the new key in this PR?**
No. The only ones I switched were:
- all of the codegen'd kernels
- all of the (recently added) `view_copy.out` kernels in native_functions.yaml
- A handful of one-off kernels that I noticed in native_functions.yaml
But there are probably a bunch more - I'm going to switch more over as part of integrating functionalization with LTC/XLA.
Differential Revision: [D35953393](https://our.internmc.facebook.com/intern/diff/D35953393)
[ghstack-poisoned]
|
@bdhirsh has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator. |
…itions"
This PR adds a new alias key for composite kernels, bringing the total count to 3. Composite kernels should be registered to this new key under the following conditions:
- The operator itself is functional (no alias annotations)
- The decomposition calls into ops that *do* have alias annotations (either mutations or views)
- The operator has a derivative formula
This alias key is similar to the `CompositeExplicitAutograd` alias key, except that the `Lazy` and `XLA` runtime keys aren't included in it (and any other future "functional" backends). That's because functional -> non-functional decompositions are not useful / kinda bad for functional backends, especially once they start using the functionalization pass (at best they introduce unnecessary overhead, at worst they can potentially cause an infinite loop with the functionalization pass).
Current key name in the PR is `CompositeExplicitAutogradWithMutations`, but I'm open to any better ideas on the name for the new key - I guess I could also use this opportunity to rename the existing composite alias keys if we think it's really worth it, although I was hoping to not have to change the existing key names :)
Other ideas:
- `CompositeExplicitAutogradNonFunctional` (better captures the fact that functional -> view decomps are also used here)
- `CompositeExplicitAutogradFunctionalToNonFunctional` (better captures the fact that the op itself should be functional, although probably way too wordy)
Note 1: in theory we could add a corresponding `CompositeImplicitAutogradWithMutations` key, but there isn't really a use case for it - it doesn't matter for functionalization, because `CompositeImplicitAutograd` kernels will *always* decompose before entering the functionalization pass.
Note 2: I was a little conflicted about what to do with mutation -> mutation decompositions (like an inplace op that decomposes to its out= variant). Semantically, I don't think it really makes sense for them to go in this key, because it doesn't matter if functional backends run them (it's only bad to *replace* a functional op with a non-functional one). We have a bunch of codegen'd `functional -> out=` and `inplace -> out=` kernels though, which I updated to get registered to the new `CompositeExplicitAutogradWithMutations` key. The `functional -> out=` kernels should definitely get registered to this key, but the `inplace -> out=` kernels probably shouldn't. But it's kind of harmless to register `inplace -> out=` kernels to the new key, and teasing that out would require adding a bunch of extra logic.
A good example of a kernel that fits this category is the `cummax` kernel, which looks like this (and cummax has a derivative formula defined):
```
std::tuple<Tensor, Tensor> cummax(const Tensor& self, int64_t dim) {
auto values = at::empty(self.sizes(), self.options());
auto indices = at::empty(self.sizes(), self.options().dtype(at::kLong));
at::cummax_out(values, indices, self, dim);
return std::make_tuple(values, indices);
}
```
**Have all of the relevant kernels been switched over to the new key in this PR?**
No. The only ones I switched were:
- all of the codegen'd kernels
- all of the (recently added) `view_copy.out` kernels in native_functions.yaml
- A handful of one-off kernels that I noticed in native_functions.yaml
But there are probably a bunch more - I'm going to switch more over as part of integrating functionalization with LTC/XLA.
Differential Revision: [D35953393](https://our.internmc.facebook.com/intern/diff/D35953393)
[ghstack-poisoned]
|
@bdhirsh has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator. |
…itions"
This PR adds a new alias key for composite kernels, bringing the total count to 3. Composite kernels should be registered to this new key under the following conditions:
- The operator itself is functional (no alias annotations)
- The decomposition calls into ops that *do* have alias annotations (either mutations or views)
- The operator has a derivative formula
This alias key is similar to the `CompositeExplicitAutograd` alias key, except that the `Lazy` and `XLA` runtime keys aren't included in it (and any other future "functional" backends). That's because functional -> non-functional decompositions are not useful / kinda bad for functional backends, especially once they start using the functionalization pass (at best they introduce unnecessary overhead, at worst they can potentially cause an infinite loop with the functionalization pass).
Current key name in the PR is `CompositeExplicitAutogradWithMutations`, but I'm open to any better ideas on the name for the new key - I guess I could also use this opportunity to rename the existing composite alias keys if we think it's really worth it, although I was hoping to not have to change the existing key names :)
Other ideas:
- `CompositeExplicitAutogradNonFunctional` (better captures the fact that functional -> view decomps are also used here)
- `CompositeExplicitAutogradFunctionalToNonFunctional` (better captures the fact that the op itself should be functional, although probably way too wordy)
Note 1: in theory we could add a corresponding `CompositeImplicitAutogradWithMutations` key, but there isn't really a use case for it - it doesn't matter for functionalization, because `CompositeImplicitAutograd` kernels will *always* decompose before entering the functionalization pass.
Note 2: I was a little conflicted about what to do with mutation -> mutation decompositions (like an inplace op that decomposes to its out= variant). Semantically, I don't think it really makes sense for them to go in this key, because it doesn't matter if functional backends run them (it's only bad to *replace* a functional op with a non-functional one). We have a bunch of codegen'd `functional -> out=` and `inplace -> out=` kernels though, which I updated to get registered to the new `CompositeExplicitAutogradWithMutations` key. The `functional -> out=` kernels should definitely get registered to this key, but the `inplace -> out=` kernels probably shouldn't. But it's kind of harmless to register `inplace -> out=` kernels to the new key, and teasing that out would require adding a bunch of extra logic.
A good example of a kernel that fits this category is the `cummax` kernel, which looks like this (and cummax has a derivative formula defined):
```
std::tuple<Tensor, Tensor> cummax(const Tensor& self, int64_t dim) {
auto values = at::empty(self.sizes(), self.options());
auto indices = at::empty(self.sizes(), self.options().dtype(at::kLong));
at::cummax_out(values, indices, self, dim);
return std::make_tuple(values, indices);
}
```
**Have all of the relevant kernels been switched over to the new key in this PR?**
No. The only ones I switched were:
- all of the codegen'd kernels
- all of the (recently added) `view_copy.out` kernels in native_functions.yaml
- A handful of one-off kernels that I noticed in native_functions.yaml
But there are probably a bunch more - I'm going to switch more over as part of integrating functionalization with LTC/XLA.
Differential Revision: [D35953393](https://our.internmc.facebook.com/intern/diff/D35953393)
[ghstack-poisoned]
…itions"
This PR adds a new alias key for composite kernels, bringing the total count to 3. Composite kernels should be registered to this new key under the following conditions:
- The operator itself is functional (no alias annotations)
- The decomposition calls into ops that *do* have alias annotations (either mutations or views)
- The operator has a derivative formula
This alias key is similar to the `CompositeExplicitAutograd` alias key, except that the `Lazy` and `XLA` runtime keys aren't included in it (and any other future "functional" backends). That's because functional -> non-functional decompositions are not useful / kinda bad for functional backends, especially once they start using the functionalization pass (at best they introduce unnecessary overhead, at worst they can potentially cause an infinite loop with the functionalization pass).
Current key name in the PR is `CompositeExplicitAutogradWithMutations`, but I'm open to any better ideas on the name for the new key - I guess I could also use this opportunity to rename the existing composite alias keys if we think it's really worth it, although I was hoping to not have to change the existing key names :)
Other ideas:
- `CompositeExplicitAutogradNonFunctional` (better captures the fact that functional -> view decomps are also used here)
- `CompositeExplicitAutogradFunctionalToNonFunctional` (better captures the fact that the op itself should be functional, although probably way too wordy)
Note 1: in theory we could add a corresponding `CompositeImplicitAutogradWithMutations` key, but there isn't really a use case for it - it doesn't matter for functionalization, because `CompositeImplicitAutograd` kernels will *always* decompose before entering the functionalization pass.
Note 2: I was a little conflicted about what to do with mutation -> mutation decompositions (like an inplace op that decomposes to its out= variant). Semantically, I don't think it really makes sense for them to go in this key, because it doesn't matter if functional backends run them (it's only bad to *replace* a functional op with a non-functional one). We have a bunch of codegen'd `functional -> out=` and `inplace -> out=` kernels though, which I updated to get registered to the new `CompositeExplicitAutogradWithMutations` key. The `functional -> out=` kernels should definitely get registered to this key, but the `inplace -> out=` kernels probably shouldn't. But it's kind of harmless to register `inplace -> out=` kernels to the new key, and teasing that out would require adding a bunch of extra logic.
A good example of a kernel that fits this category is the `cummax` kernel, which looks like this (and cummax has a derivative formula defined):
```
std::tuple<Tensor, Tensor> cummax(const Tensor& self, int64_t dim) {
auto values = at::empty(self.sizes(), self.options());
auto indices = at::empty(self.sizes(), self.options().dtype(at::kLong));
at::cummax_out(values, indices, self, dim);
return std::make_tuple(values, indices);
}
```
**Have all of the relevant kernels been switched over to the new key in this PR?**
No. The only ones I switched were:
- all of the codegen'd kernels
- all of the (recently added) `view_copy.out` kernels in native_functions.yaml
- A handful of one-off kernels that I noticed in native_functions.yaml
But there are probably a bunch more - I'm going to switch more over as part of integrating functionalization with LTC/XLA.
Differential Revision: [D35953393](https://our.internmc.facebook.com/intern/diff/D35953393)
[ghstack-poisoned]
…itions"
This PR adds a new alias key for composite kernels, bringing the total count to 3. Composite kernels should be registered to this new key under the following conditions:
- The operator itself is functional (no alias annotations)
- The decomposition calls into ops that *do* have alias annotations (either mutations or views)
- The operator has a derivative formula
This alias key is similar to the `CompositeExplicitAutograd` alias key, except that the `Lazy` and `XLA` runtime keys aren't included in it (and any other future "functional" backends). That's because functional -> non-functional decompositions are not useful / kinda bad for functional backends, especially once they start using the functionalization pass (at best they introduce unnecessary overhead, at worst they can potentially cause an infinite loop with the functionalization pass).
Current key name in the PR is `CompositeExplicitAutogradWithMutations`, but I'm open to any better ideas on the name for the new key - I guess I could also use this opportunity to rename the existing composite alias keys if we think it's really worth it, although I was hoping to not have to change the existing key names :)
Other ideas:
- `CompositeExplicitAutogradNonFunctional` (better captures the fact that functional -> view decomps are also used here)
- `CompositeExplicitAutogradFunctionalToNonFunctional` (better captures the fact that the op itself should be functional, although probably way too wordy)
Note 1: in theory we could add a corresponding `CompositeImplicitAutogradWithMutations` key, but there isn't really a use case for it - it doesn't matter for functionalization, because `CompositeImplicitAutograd` kernels will *always* decompose before entering the functionalization pass.
Note 2: I was a little conflicted about what to do with mutation -> mutation decompositions (like an inplace op that decomposes to its out= variant). Semantically, I don't think it really makes sense for them to go in this key, because it doesn't matter if functional backends run them (it's only bad to *replace* a functional op with a non-functional one). We have a bunch of codegen'd `functional -> out=` and `inplace -> out=` kernels though, which I updated to get registered to the new `CompositeExplicitAutogradWithMutations` key. The `functional -> out=` kernels should definitely get registered to this key, but the `inplace -> out=` kernels probably shouldn't. But it's kind of harmless to register `inplace -> out=` kernels to the new key, and teasing that out would require adding a bunch of extra logic.
A good example of a kernel that fits this category is the `cummax` kernel, which looks like this (and cummax has a derivative formula defined):
```
std::tuple<Tensor, Tensor> cummax(const Tensor& self, int64_t dim) {
auto values = at::empty(self.sizes(), self.options());
auto indices = at::empty(self.sizes(), self.options().dtype(at::kLong));
at::cummax_out(values, indices, self, dim);
return std::make_tuple(values, indices);
}
```
**Have all of the relevant kernels been switched over to the new key in this PR?**
No. The only ones I switched were:
- all of the codegen'd kernels
- all of the (recently added) `view_copy.out` kernels in native_functions.yaml
- A handful of one-off kernels that I noticed in native_functions.yaml
But there are probably a bunch more - I'm going to switch more over as part of integrating functionalization with LTC/XLA.
Differential Revision: [D35953393](https://our.internmc.facebook.com/intern/diff/D35953393)
[ghstack-poisoned]
|
@bdhirsh has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator. |
…itions"
This PR adds a new alias key for composite kernels, bringing the total count to 3. Composite kernels should be registered to this new key under the following conditions:
- The operator itself is functional (no alias annotations)
- The decomposition calls into ops that *do* have alias annotations (either mutations or views)
- The operator has a derivative formula
This alias key is similar to the `CompositeExplicitAutograd` alias key, except that the `Lazy` and `XLA` runtime keys aren't included in it (and any other future "functional" backends). That's because functional -> non-functional decompositions are not useful / kinda bad for functional backends, especially once they start using the functionalization pass (at best they introduce unnecessary overhead, at worst they can potentially cause an infinite loop with the functionalization pass).
Current key name in the PR is `CompositeExplicitAutogradWithMutations`, but I'm open to any better ideas on the name for the new key - I guess I could also use this opportunity to rename the existing composite alias keys if we think it's really worth it, although I was hoping to not have to change the existing key names :)
Other ideas:
- `CompositeExplicitAutogradNonFunctional` (better captures the fact that functional -> view decomps are also used here)
- `CompositeExplicitAutogradFunctionalToNonFunctional` (better captures the fact that the op itself should be functional, although probably way too wordy)
Note 1: in theory we could add a corresponding `CompositeImplicitAutogradWithMutations` key, but there isn't really a use case for it - it doesn't matter for functionalization, because `CompositeImplicitAutograd` kernels will *always* decompose before entering the functionalization pass.
Note 2: I was a little conflicted about what to do with mutation -> mutation decompositions (like an inplace op that decomposes to its out= variant). Semantically, I don't think it really makes sense for them to go in this key, because it doesn't matter if functional backends run them (it's only bad to *replace* a functional op with a non-functional one). We have a bunch of codegen'd `functional -> out=` and `inplace -> out=` kernels though, which I updated to get registered to the new `CompositeExplicitAutogradWithMutations` key. The `functional -> out=` kernels should definitely get registered to this key, but the `inplace -> out=` kernels probably shouldn't. But it's kind of harmless to register `inplace -> out=` kernels to the new key, and teasing that out would require adding a bunch of extra logic.
A good example of a kernel that fits this category is the `cummax` kernel, which looks like this (and cummax has a derivative formula defined):
```
std::tuple<Tensor, Tensor> cummax(const Tensor& self, int64_t dim) {
auto values = at::empty(self.sizes(), self.options());
auto indices = at::empty(self.sizes(), self.options().dtype(at::kLong));
at::cummax_out(values, indices, self, dim);
return std::make_tuple(values, indices);
}
```
**Have all of the relevant kernels been switched over to the new key in this PR?**
No. The only ones I switched were:
- all of the codegen'd kernels
- all of the (recently added) `view_copy.out` kernels in native_functions.yaml
- A handful of one-off kernels that I noticed in native_functions.yaml
But there are probably a bunch more - I'm going to switch more over as part of integrating functionalization with LTC/XLA.
Differential Revision: [D35953393](https://our.internmc.facebook.com/intern/diff/D35953393)
[ghstack-poisoned]
…itions"
This PR adds a new alias key for composite kernels, bringing the total count to 3. Composite kernels should be registered to this new key under the following conditions:
- The operator itself is functional (no alias annotations)
- The decomposition calls into ops that *do* have alias annotations (either mutations or views)
- The operator has a derivative formula
This alias key is similar to the `CompositeExplicitAutograd` alias key, except that the `Lazy` and `XLA` runtime keys aren't included in it (and any other future "functional" backends). That's because functional -> non-functional decompositions are not useful / kinda bad for functional backends, especially once they start using the functionalization pass (at best they introduce unnecessary overhead, at worst they can potentially cause an infinite loop with the functionalization pass).
Current key name in the PR is `CompositeExplicitAutogradWithMutations`, but I'm open to any better ideas on the name for the new key - I guess I could also use this opportunity to rename the existing composite alias keys if we think it's really worth it, although I was hoping to not have to change the existing key names :)
Other ideas:
- `CompositeExplicitAutogradNonFunctional` (better captures the fact that functional -> view decomps are also used here)
- `CompositeExplicitAutogradFunctionalToNonFunctional` (better captures the fact that the op itself should be functional, although probably way too wordy)
Note 1: in theory we could add a corresponding `CompositeImplicitAutogradWithMutations` key, but there isn't really a use case for it - it doesn't matter for functionalization, because `CompositeImplicitAutograd` kernels will *always* decompose before entering the functionalization pass.
Note 2: I was a little conflicted about what to do with mutation -> mutation decompositions (like an inplace op that decomposes to its out= variant). Semantically, I don't think it really makes sense for them to go in this key, because it doesn't matter if functional backends run them (it's only bad to *replace* a functional op with a non-functional one). We have a bunch of codegen'd `functional -> out=` and `inplace -> out=` kernels though, which I updated to get registered to the new `CompositeExplicitAutogradWithMutations` key. The `functional -> out=` kernels should definitely get registered to this key, but the `inplace -> out=` kernels probably shouldn't. But it's kind of harmless to register `inplace -> out=` kernels to the new key, and teasing that out would require adding a bunch of extra logic.
A good example of a kernel that fits this category is the `cummax` kernel, which looks like this (and cummax has a derivative formula defined):
```
std::tuple<Tensor, Tensor> cummax(const Tensor& self, int64_t dim) {
auto values = at::empty(self.sizes(), self.options());
auto indices = at::empty(self.sizes(), self.options().dtype(at::kLong));
at::cummax_out(values, indices, self, dim);
return std::make_tuple(values, indices);
}
```
**Have all of the relevant kernels been switched over to the new key in this PR?**
No. The only ones I switched were:
- all of the codegen'd kernels
- all of the (recently added) `view_copy.out` kernels in native_functions.yaml
- A handful of one-off kernels that I noticed in native_functions.yaml
But there are probably a bunch more - I'm going to switch more over as part of integrating functionalization with LTC/XLA.
Differential Revision: [D35953393](https://our.internmc.facebook.com/intern/diff/D35953393)
[ghstack-poisoned]
…itions"
This PR adds a new alias key for composite kernels, bringing the total count to 3. Composite kernels should be registered to this new key under the following conditions:
- The operator itself is functional (no alias annotations)
- The decomposition calls into ops that *do* have alias annotations (either mutations or views)
- The operator has a derivative formula
This alias key is similar to the `CompositeExplicitAutograd` alias key, except that the `Lazy` and `XLA` runtime keys aren't included in it (and any other future "functional" backends). That's because functional -> non-functional decompositions are not useful / kinda bad for functional backends, especially once they start using the functionalization pass (at best they introduce unnecessary overhead, at worst they can potentially cause an infinite loop with the functionalization pass).
Current key name in the PR is `CompositeExplicitAutogradWithMutations`, but I'm open to any better ideas on the name for the new key - I guess I could also use this opportunity to rename the existing composite alias keys if we think it's really worth it, although I was hoping to not have to change the existing key names :)
Other ideas:
- `CompositeExplicitAutogradNonFunctional` (better captures the fact that functional -> view decomps are also used here)
- `CompositeExplicitAutogradFunctionalToNonFunctional` (better captures the fact that the op itself should be functional, although probably way too wordy)
Note 1: in theory we could add a corresponding `CompositeImplicitAutogradWithMutations` key, but there isn't really a use case for it - it doesn't matter for functionalization, because `CompositeImplicitAutograd` kernels will *always* decompose before entering the functionalization pass.
Note 2: I was a little conflicted about what to do with mutation -> mutation decompositions (like an inplace op that decomposes to its out= variant). Semantically, I don't think it really makes sense for them to go in this key, because it doesn't matter if functional backends run them (it's only bad to *replace* a functional op with a non-functional one). We have a bunch of codegen'd `functional -> out=` and `inplace -> out=` kernels though, which I updated to get registered to the new `CompositeExplicitAutogradWithMutations` key. The `functional -> out=` kernels should definitely get registered to this key, but the `inplace -> out=` kernels probably shouldn't. But it's kind of harmless to register `inplace -> out=` kernels to the new key, and teasing that out would require adding a bunch of extra logic.
A good example of a kernel that fits this category is the `cummax` kernel, which looks like this (and cummax has a derivative formula defined):
```
std::tuple<Tensor, Tensor> cummax(const Tensor& self, int64_t dim) {
auto values = at::empty(self.sizes(), self.options());
auto indices = at::empty(self.sizes(), self.options().dtype(at::kLong));
at::cummax_out(values, indices, self, dim);
return std::make_tuple(values, indices);
}
```
**Have all of the relevant kernels been switched over to the new key in this PR?**
No. The only ones I switched were:
- all of the codegen'd kernels
- all of the (recently added) `view_copy.out` kernels in native_functions.yaml
- A handful of one-off kernels that I noticed in native_functions.yaml
But there are probably a bunch more - I'm going to switch more over as part of integrating functionalization with LTC/XLA.
Differential Revision: [D35953393](https://our.internmc.facebook.com/intern/diff/D35953393)
[ghstack-poisoned]
…itions"
This PR adds a new alias key for composite kernels, bringing the total count to 3. Composite kernels should be registered to this new key under the following conditions:
- The operator itself is functional (no alias annotations)
- The decomposition calls into ops that *do* have alias annotations (either mutations or views)
- The operator has a derivative formula
This alias key is similar to the `CompositeExplicitAutograd` alias key, except that the `Lazy` and `XLA` runtime keys aren't included in it (and any other future "functional" backends). That's because functional -> non-functional decompositions are not useful / kinda bad for functional backends, especially once they start using the functionalization pass (at best they introduce unnecessary overhead, at worst they can potentially cause an infinite loop with the functionalization pass).
Current key name in the PR is `CompositeExplicitAutogradWithMutations`, but I'm open to any better ideas on the name for the new key - I guess I could also use this opportunity to rename the existing composite alias keys if we think it's really worth it, although I was hoping to not have to change the existing key names :)
Other ideas:
- `CompositeExplicitAutogradNonFunctional` (better captures the fact that functional -> view decomps are also used here)
- `CompositeExplicitAutogradFunctionalToNonFunctional` (better captures the fact that the op itself should be functional, although probably way too wordy)
Note 1: in theory we could add a corresponding `CompositeImplicitAutogradWithMutations` key, but there isn't really a use case for it - it doesn't matter for functionalization, because `CompositeImplicitAutograd` kernels will *always* decompose before entering the functionalization pass.
Note 2: I was a little conflicted about what to do with mutation -> mutation decompositions (like an inplace op that decomposes to its out= variant). Semantically, I don't think it really makes sense for them to go in this key, because it doesn't matter if functional backends run them (it's only bad to *replace* a functional op with a non-functional one). We have a bunch of codegen'd `functional -> out=` and `inplace -> out=` kernels though, which I updated to get registered to the new `CompositeExplicitAutogradWithMutations` key. The `functional -> out=` kernels should definitely get registered to this key, but the `inplace -> out=` kernels probably shouldn't. But it's kind of harmless to register `inplace -> out=` kernels to the new key, and teasing that out would require adding a bunch of extra logic.
A good example of a kernel that fits this category is the `cummax` kernel, which looks like this (and cummax has a derivative formula defined):
```
std::tuple<Tensor, Tensor> cummax(const Tensor& self, int64_t dim) {
auto values = at::empty(self.sizes(), self.options());
auto indices = at::empty(self.sizes(), self.options().dtype(at::kLong));
at::cummax_out(values, indices, self, dim);
return std::make_tuple(values, indices);
}
```
**Have all of the relevant kernels been switched over to the new key in this PR?**
No. The only ones I switched were:
- all of the codegen'd kernels
- all of the (recently added) `view_copy.out` kernels in native_functions.yaml
- A handful of one-off kernels that I noticed in native_functions.yaml
But there are probably a bunch more - I'm going to switch more over as part of integrating functionalization with LTC/XLA.
Differential Revision: [D35953393](https://our.internmc.facebook.com/intern/diff/D35953393)
[ghstack-poisoned]
…itions"
This PR adds a new alias key for composite kernels, bringing the total count to 3. Composite kernels should be registered to this new key under the following conditions:
- The operator itself is functional (no alias annotations)
- The decomposition calls into ops that *do* have alias annotations (either mutations or views)
- The operator has a derivative formula
This alias key is similar to the `CompositeExplicitAutograd` alias key, except that the `Lazy` and `XLA` runtime keys aren't included in it (and any other future "functional" backends). That's because functional -> non-functional decompositions are not useful / kinda bad for functional backends, especially once they start using the functionalization pass (at best they introduce unnecessary overhead, at worst they can potentially cause an infinite loop with the functionalization pass).
Current key name in the PR is `CompositeExplicitAutogradWithMutations`, but I'm open to any better ideas on the name for the new key - I guess I could also use this opportunity to rename the existing composite alias keys if we think it's really worth it, although I was hoping to not have to change the existing key names :)
Other ideas:
- `CompositeExplicitAutogradNonFunctional` (better captures the fact that functional -> view decomps are also used here)
- `CompositeExplicitAutogradFunctionalToNonFunctional` (better captures the fact that the op itself should be functional, although probably way too wordy)
Note 1: in theory we could add a corresponding `CompositeImplicitAutogradWithMutations` key, but there isn't really a use case for it - it doesn't matter for functionalization, because `CompositeImplicitAutograd` kernels will *always* decompose before entering the functionalization pass.
Note 2: I was a little conflicted about what to do with mutation -> mutation decompositions (like an inplace op that decomposes to its out= variant). Semantically, I don't think it really makes sense for them to go in this key, because it doesn't matter if functional backends run them (it's only bad to *replace* a functional op with a non-functional one). We have a bunch of codegen'd `functional -> out=` and `inplace -> out=` kernels though, which I updated to get registered to the new `CompositeExplicitAutogradWithMutations` key. The `functional -> out=` kernels should definitely get registered to this key, but the `inplace -> out=` kernels probably shouldn't. But it's kind of harmless to register `inplace -> out=` kernels to the new key, and teasing that out would require adding a bunch of extra logic.
A good example of a kernel that fits this category is the `cummax` kernel, which looks like this (and cummax has a derivative formula defined):
```
std::tuple<Tensor, Tensor> cummax(const Tensor& self, int64_t dim) {
auto values = at::empty(self.sizes(), self.options());
auto indices = at::empty(self.sizes(), self.options().dtype(at::kLong));
at::cummax_out(values, indices, self, dim);
return std::make_tuple(values, indices);
}
```
**Have all of the relevant kernels been switched over to the new key in this PR?**
No. The only ones I switched were:
- all of the codegen'd kernels
- all of the (recently added) `view_copy.out` kernels in native_functions.yaml
- A handful of one-off kernels that I noticed in native_functions.yaml
But there are probably a bunch more - I'm going to switch more over as part of integrating functionalization with LTC/XLA.
Differential Revision: [D35953393](https://our.internmc.facebook.com/intern/diff/D35953393)
[ghstack-poisoned]
…itions"
This PR adds a new alias key for composite kernels, bringing the total count to 3. Composite kernels should be registered to this new key under the following conditions:
- The operator itself is functional (no alias annotations)
- The decomposition calls into ops that *do* have alias annotations (either mutations or views)
- The operator has a derivative formula
This alias key is similar to the `CompositeExplicitAutograd` alias key, except that the `Lazy` and `XLA` runtime keys aren't included in it (and any other future "functional" backends). That's because functional -> non-functional decompositions are not useful / kinda bad for functional backends, especially once they start using the functionalization pass (at best they introduce unnecessary overhead, at worst they can potentially cause an infinite loop with the functionalization pass).
Current key name in the PR is `CompositeExplicitAutogradWithMutations`, but I'm open to any better ideas on the name for the new key - I guess I could also use this opportunity to rename the existing composite alias keys if we think it's really worth it, although I was hoping to not have to change the existing key names :)
Other ideas:
- `CompositeExplicitAutogradNonFunctional` (better captures the fact that functional -> view decomps are also used here)
- `CompositeExplicitAutogradFunctionalToNonFunctional` (better captures the fact that the op itself should be functional, although probably way too wordy)
Note 1: in theory we could add a corresponding `CompositeImplicitAutogradWithMutations` key, but there isn't really a use case for it - it doesn't matter for functionalization, because `CompositeImplicitAutograd` kernels will *always* decompose before entering the functionalization pass.
Note 2: I was a little conflicted about what to do with mutation -> mutation decompositions (like an inplace op that decomposes to its out= variant). Semantically, I don't think it really makes sense for them to go in this key, because it doesn't matter if functional backends run them (it's only bad to *replace* a functional op with a non-functional one). We have a bunch of codegen'd `functional -> out=` and `inplace -> out=` kernels though, which I updated to get registered to the new `CompositeExplicitAutogradWithMutations` key. The `functional -> out=` kernels should definitely get registered to this key, but the `inplace -> out=` kernels probably shouldn't. But it's kind of harmless to register `inplace -> out=` kernels to the new key, and teasing that out would require adding a bunch of extra logic.
A good example of a kernel that fits this category is the `cummax` kernel, which looks like this (and cummax has a derivative formula defined):
```
std::tuple<Tensor, Tensor> cummax(const Tensor& self, int64_t dim) {
auto values = at::empty(self.sizes(), self.options());
auto indices = at::empty(self.sizes(), self.options().dtype(at::kLong));
at::cummax_out(values, indices, self, dim);
return std::make_tuple(values, indices);
}
```
**Have all of the relevant kernels been switched over to the new key in this PR?**
No. The only ones I switched were:
- all of the codegen'd kernels
- all of the (recently added) `view_copy.out` kernels in native_functions.yaml
- A handful of one-off kernels that I noticed in native_functions.yaml
But there are probably a bunch more - I'm going to switch more over as part of integrating functionalization with LTC/XLA.
Differential Revision: [D35953393](https://our.internmc.facebook.com/intern/diff/D35953393)
[ghstack-poisoned]
…positions"
This PR adds a new alias key for composite kernels, bringing the total count to 3. Composite kernels should be registered to this new key under the following conditions:
- The operator itself is functional (no alias annotations)
- The decomposition calls into ops that *do* have alias annotations (either mutations or views)
- The operator has a derivative formula
This alias key is similar to the `CompositeExplicitAutograd` alias key, except that the `Lazy` and `XLA` runtime keys aren't included in it (and any other future "functional" backends). That's because functional -> non-functional decompositions are not useful / kinda bad for functional backends, especially once they start using the functionalization pass (at best they introduce unnecessary overhead, at worst they can potentially cause an infinite loop with the functionalization pass).
Current key name in the PR is `CompositeExplicitAutogradWithMutations`, but I'm open to any better ideas on the name for the new key - I guess I could also use this opportunity to rename the existing composite alias keys if we think it's really worth it, although I was hoping to not have to change the existing key names :)
Other ideas:
- `CompositeExplicitAutogradNonFunctional` (better captures the fact that functional -> view decomps are also used here)
- `CompositeExplicitAutogradFunctionalToNonFunctional` (better captures the fact that the op itself should be functional, although probably way too wordy)
Note 1: in theory we could add a corresponding `CompositeImplicitAutogradWithMutations` key, but there isn't really a use case for it - it doesn't matter for functionalization, because `CompositeImplicitAutograd` kernels will *always* decompose before entering the functionalization pass.
Note 2: I was a little conflicted about what to do with mutation -> mutation decompositions (like an inplace op that decomposes to its out= variant). Semantically, I don't think it really makes sense for them to go in this key, because it doesn't matter if functional backends run them (it's only bad to *replace* a functional op with a non-functional one). We have a bunch of codegen'd `functional -> out=` and `inplace -> out=` kernels though, which I updated to get registered to the new `CompositeExplicitAutogradWithMutations` key. The `functional -> out=` kernels should definitely get registered to this key, but the `inplace -> out=` kernels probably shouldn't. But it's kind of harmless to register `inplace -> out=` kernels to the new key, and teasing that out would require adding a bunch of extra logic.
A good example of a kernel that fits this category is the `cummax` kernel, which looks like this (and cummax has a derivative formula defined):
```
std::tuple<Tensor, Tensor> cummax(const Tensor& self, int64_t dim) {
auto values = at::empty(self.sizes(), self.options());
auto indices = at::empty(self.sizes(), self.options().dtype(at::kLong));
at::cummax_out(values, indices, self, dim);
return std::make_tuple(values, indices);
}
```
**Have all of the relevant kernels been switched over to the new key in this PR?**
No. The only ones I switched were:
- all of the codegen'd kernels
- all of the (recently added) `view_copy.out` kernels in native_functions.yaml
- A handful of one-off kernels that I noticed in native_functions.yaml
But there are probably a bunch more - I'm going to switch more over as part of integrating functionalization with LTC/XLA.
Differential Revision: [D35953393](https://our.internmc.facebook.com/intern/diff/D35953393)
[ghstack-poisoned]
|
Looks like this PR hasn't been updated in a while so we're going to go ahead and mark this as |
This PR adds a new alias key for composite kernels, bringing the total count to 3. Composite kernels should be registered to this new key under the following conditions:
This alias key is similar to the
CompositeExplicitAutogradalias key, except that theLazyandXLAruntime keys aren't included in it (and any other future "functional" backends). That's because functional -> non-functional decompositions are not useful / kinda bad for functional backends, especially once they start using the functionalization pass (at best they introduce unnecessary overhead, at worst they can potentially cause an infinite loop with the functionalization pass).Current key name in the PR is
CompositeExplicitAutogradWithMutations, but I'm open to any better ideas on the name for the new key - I guess I could also use this opportunity to rename the existing composite alias keys if we think it's really worth it, although I was hoping to not have to change the existing key names :)Other ideas:
CompositeExplicitAutogradNonFunctional(better captures the fact that functional -> view decomps are also used here)CompositeExplicitAutogradFunctionalToNonFunctional(better captures the fact that the op itself should be functional, although probably way too wordy)Note 1: in theory we could add a corresponding
CompositeImplicitAutogradWithMutationskey, but there isn't really a use case for it - it doesn't matter for functionalization, becauseCompositeImplicitAutogradkernels will always decompose before entering the functionalization pass.Note 2: I was a little conflicted about what to do with mutation -> mutation decompositions (like an inplace op that decomposes to its out= variant). Semantically, I don't think it really makes sense for them to go in this key, because it doesn't matter if functional backends run them (it's only bad to replace a functional op with a non-functional one). We have a bunch of codegen'd
functional -> out=andinplace -> out=kernels though, which I updated to get registered to the newCompositeExplicitAutogradWithMutationskey. Thefunctional -> out=kernels should definitely get registered to this key, but theinplace -> out=kernels probably shouldn't. But it's kind of harmless to registerinplace -> out=kernels to the new key, and teasing that out would require adding a bunch of extra logic.A good example of a kernel that fits this category is the
cummaxkernel, which looks like this (and cummax has a derivative formula defined):Have all of the relevant kernels been switched over to the new key in this PR?
No. The only ones I switched were:
view_copy.outkernels in native_functions.yamlBut there are probably a bunch more - I'm going to switch more over as part of integrating functionalization with LTC/XLA.
Stack from ghstack:
Differential Revision: D35953393