Skip to content

add a new alias key for functional to non functional decompositions#76358

Closed
bdhirsh wants to merge 40 commits intogh/bdhirsh/220/basefrom
gh/bdhirsh/220/head
Closed

add a new alias key for functional to non functional decompositions#76358
bdhirsh wants to merge 40 commits intogh/bdhirsh/220/basefrom
gh/bdhirsh/220/head

Conversation

@bdhirsh
Copy link
Collaborator

@bdhirsh bdhirsh commented Apr 26, 2022

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.

Stack from ghstack:

Differential Revision: D35953393

@facebook-github-bot
Copy link
Contributor

facebook-github-bot commented Apr 26, 2022

🔗 Helpful links

❌ 2 New Failures

As of commit 0778a55 (more details on the Dr. CI page):

Expand to see more
  • 2/2 failures introduced in this PR

🕵️ 2 new failures recognized by patterns

The following CI failures do not appear to be due to upstream breakages

See GitHub Actions build pull / win-vs2019-cpu-py3 / test (default, 1, 2, windows.4xlarge) (1/2)

Step: "Test" (full log | diagnosis details | 🔁 rerun)

2022-06-15T16:26:04.1240428Z Build left local git repository checkout dirty
2022-06-15T16:26:03.8997457Z + assert_git_not_dirty
2022-06-15T16:26:03.8997729Z + [[ win-vs2019-cpu-py3 != *rocm* ]]
2022-06-15T16:26:03.8997969Z + [[ win-vs2019-cpu-py3 != *xla* ]]
2022-06-15T16:26:03.9073512Z ++ git status --porcelain
2022-06-15T16:26:04.1238829Z + git_status='?? nonfunctional'
2022-06-15T16:26:04.1239293Z + [[ -n ?? nonfunctional ]]
2022-06-15T16:26:04.1239567Z + echo 'Build left local git repository checkout dirty'
2022-06-15T16:26:04.1239816Z + echo 'git status --porcelain:'
2022-06-15T16:26:04.1240035Z + echo '?? nonfunctional'
2022-06-15T16:26:04.1240216Z + exit 1
2022-06-15T16:26:04.1240428Z Build left local git repository checkout dirty
2022-06-15T16:26:04.1240660Z git status --porcelain:
2022-06-15T16:26:04.1240853Z ?? nonfunctional
2022-06-15T16:26:04.1241016Z + cleanup
2022-06-15T16:26:04.1241180Z + retcode=1
2022-06-15T16:26:04.1241341Z + set +x
2022-06-15T16:26:04.1274450Z ##[error]Process completed with exit code 1.
2022-06-15T16:26:04.1413485Z Prepare all required actions
2022-06-15T16:26:04.1414024Z Getting action download info
2022-06-15T16:26:04.3116854Z Download action repository 'nick-fields/retry@71062288b76e2b6214ebde0e673ce0de1755740a' (SHA:71062288b76e2b6214ebde0e673ce0de1755740a)
2022-06-15T16:26:04.5832316Z ##[group]Run ./.github/actions/get-workflow-job-id

See GitHub Actions build pull / win-vs2019-cpu-py3 / test (default, 2, 2, windows.4xlarge) (2/2)

Step: "Test" (full log | diagnosis details | 🔁 rerun)

2022-06-15T16:22:38.4326580Z Build left local git repository checkout dirty
2022-06-15T16:22:37.1638453Z + assert_git_not_dirty
2022-06-15T16:22:37.1638736Z + [[ win-vs2019-cpu-py3 != *rocm* ]]
2022-06-15T16:22:37.1638970Z + [[ win-vs2019-cpu-py3 != *xla* ]]
2022-06-15T16:22:37.1712370Z ++ git status --porcelain
2022-06-15T16:22:38.4325162Z + git_status='?? nonfunctional'
2022-06-15T16:22:38.4325453Z + [[ -n ?? nonfunctional ]]
2022-06-15T16:22:38.4325716Z + echo 'Build left local git repository checkout dirty'
2022-06-15T16:22:38.4325963Z + echo 'git status --porcelain:'
2022-06-15T16:22:38.4326192Z + echo '?? nonfunctional'
2022-06-15T16:22:38.4326375Z + exit 1
2022-06-15T16:22:38.4326580Z Build left local git repository checkout dirty
2022-06-15T16:22:38.4326990Z git status --porcelain:
2022-06-15T16:22:38.4327181Z ?? nonfunctional
2022-06-15T16:22:38.4331187Z + cleanup
2022-06-15T16:22:38.4331364Z + retcode=1
2022-06-15T16:22:38.4331659Z + set +x
2022-06-15T16:22:38.4371933Z ##[error]Process completed with exit code 1.
2022-06-15T16:22:38.4607459Z Prepare all required actions
2022-06-15T16:22:38.4607914Z Getting action download info
2022-06-15T16:22:38.6546294Z Download action repository 'nick-fields/retry@71062288b76e2b6214ebde0e673ce0de1755740a' (SHA:71062288b76e2b6214ebde0e673ce0de1755740a)
2022-06-15T16:22:38.8496231Z ##[group]Run ./.github/actions/get-workflow-job-id

This comment was automatically generated by Dr. CI (expand for details).

Please report bugs/suggestions to the (internal) Dr. CI Users group.

Click here to manually regenerate this comment.

bdhirsh added a commit that referenced this pull request Apr 26, 2022
bdhirsh added a commit that referenced this pull request Apr 27, 2022
@bdhirsh
Copy link
Collaborator Author

bdhirsh commented Apr 27, 2022

@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
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I figured that the CompositeExplicitAutogradWithMutations kernels should get higher precedence, since they belong to a more specific group of dispatch keys than CompositeExplicitAutograd

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't follow. I could have renamed these CompositeExplicitAutograd and CompositeExplicitAutogradWithoutMutations and it seems to me like the latter is more specific!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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:
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 added a commit that referenced this pull request Apr 27, 2022
@bdhirsh
Copy link
Collaborator Author

bdhirsh commented Apr 27, 2022

@bdhirsh has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@bdhirsh bdhirsh requested review from albanD and ezyang April 27, 2022 14:09
@ezyang ezyang requested a review from Chillee May 1, 2022 00:23
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.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 "
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Collaborator Author

@bdhirsh bdhirsh May 5, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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]
bdhirsh added 3 commits June 6, 2022 20:04
…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
Copy link
Collaborator Author

bdhirsh commented Jun 8, 2022

@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
Copy link
Collaborator Author

bdhirsh commented Jun 8, 2022

@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
Copy link
Collaborator Author

bdhirsh commented Jun 8, 2022

@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
Copy link
Collaborator Author

bdhirsh commented Jun 8, 2022

@bdhirsh has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

bdhirsh added 3 commits June 8, 2022 13:26
…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
Copy link
Collaborator Author

bdhirsh commented Jun 8, 2022

@bdhirsh has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

bdhirsh added 3 commits June 9, 2022 07:47
…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 added 2 commits June 13, 2022 12:52
…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 bdhirsh changed the title add a new alias key for functional->nonfunctional decompositions add a new alias key for functional to non functional decompositions Jun 15, 2022
…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]
@github-actions
Copy link
Contributor

Looks like this PR hasn't been updated in a while so we're going to go ahead and mark this as Stale.
Feel free to remove the Stale label if you feel this was a mistake.
If you are unable to remove the Stale label please contact a maintainer in order to do so.
If you want the bot to never mark this PR stale again, add the no-stale label.
Stale pull requests will automatically be closed after 30 days of inactivity.

@github-actions github-actions bot added the Stale label Aug 14, 2022
@bdhirsh bdhirsh closed this Aug 15, 2022
@facebook-github-bot facebook-github-bot deleted the gh/bdhirsh/220/head branch September 15, 2022 14:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants