Skip to content

Move TensorOptions ops to c10#39492

Closed
smessmer wants to merge 35 commits intogh/smessmer/224/basefrom
gh/smessmer/224/head
Closed

Move TensorOptions ops to c10#39492
smessmer wants to merge 35 commits intogh/smessmer/224/basefrom
gh/smessmer/224/head

Conversation

@smessmer
Copy link
Contributor

@smessmer smessmer commented Jun 3, 2020

Stack from ghstack:

This PR adds use_c10_dispatcher: full to ops taking TensorOptions. To allow this, since the c10 operator library doesn't know about TensorOptions, we need to register the operator kernels as optional<ScalarType>, optional<Device>, optional<Layout>, optional<bool> instead, and also call them this way.

Changes:

  • Add use_c10_dispatcher: full to those ops
  • Write hacky_wrapper_for_legacy_signatures which takes an old-style kernel (i.e. one written to take TensorOptions) an creates a wrapper kernel for it that takes the scattered optional<ScalarType>, optional<Device>, optional<Layout>, optional<bool> instead.
  • Change codegen so that all op registrations are wrapped into hacky_wrapper_for_legacy_signatures. This is added to all ops but is a no-op if the op doesn't take TensorOptions. This allows us in the future to just change a kernel signature from TensorOptions to the scattered version and have it work without having to touch codegen.
  • Change codegen so that the frontend calls those operators with expanded arguments instead of with a TensorOptions object. This is required because now the kernels are written in this way.

This PR does not remove TensorOptions special cases from codegen, but instead it separates kernels from the codegen/frontend issues. After this, kernels can be worked on separately without having to touch codegen and codegen can be worked on without having to touch kernels.

Codegen diff: P133121032

Differential Revision: D21581908

Differential Revision: [D21581908](https://our.internmc.facebook.com/intern/diff/D21581908/)

[ghstack-poisoned]
smessmer added a commit that referenced this pull request Jun 3, 2020
Differential Revision: [D21581908](https://our.internmc.facebook.com/intern/diff/D21581908/)

ghstack-source-id: 105217041
Pull Request resolved: #39492
@dr-ci
Copy link

dr-ci bot commented Jun 3, 2020

💊 CI failures summary and remediations

As of commit 58bd7ff (more details on the Dr. CI page):


  • 1/1 failures introduced in this PR

XLA failure

Job pytorch_xla_linux_bionic_py3_6_clang9_build is failing. Please create an issue with title prefixed by [PT_BREAK] in pytorch/xla and link to to this PR. If you have questions, please reach out to @ailzhang / @dlibenzi / @JackCaoG.


This comment was automatically generated by Dr. CI (expand for details).Follow this link to opt-out of these comments for your Pull Requests.

Please report bugs/suggestions on the GitHub issue tracker or post in the (internal) Dr. CI Users group.

See how this bot performed.

This comment has been revised 215 times.

smessmer added a commit that referenced this pull request Jun 5, 2020
Pull Request resolved: #39492


ghstack-source-id: 105363132

Differential Revision: [D21581908](https://our.internmc.facebook.com/intern/diff/D21581908/)
@smessmer smessmer requested review from bhosmer and ezyang June 5, 2020 22:03
smessmer added a commit that referenced this pull request Jun 5, 2020
Pull Request resolved: #39492


ghstack-source-id: 105374944

Differential Revision: [D21581908](https://our.internmc.facebook.com/intern/diff/D21581908/)
@ezyang
Copy link
Contributor

ezyang commented Jun 8, 2020

This PR is pretty long, can we get a longer PR description?

@ailzhang ailzhang self-requested a review June 9, 2020 21:06
smessmer added a commit that referenced this pull request Jun 10, 2020
Pull Request resolved: #39492


ghstack-source-id: 105637896

Differential Revision: [D21581908](https://our.internmc.facebook.com/intern/diff/D21581908/)
smessmer added 2 commits June 17, 2020 15:00
This PR adds `use_c10_dispatcher: full` to ops taking `TensorOptions`. To allow this, since the c10 operator library doesn't know about `TensorOptions`, we need to register the operator kernels as `optional<ScalarType>, optional<Device>, optional<Layout>, optional<bool>` instead, and also call them this way.

Changes:
- Add `use_c10_dispatcher: full` to those ops
- Write hacky_wrapper_for_legacy_signatures which takes an old-style kernel (i.e. one written to take `TensorOptions`) an creates a wrapper kernel for it that takes the scattered `optional<ScalarType>, optional<Device>, optional<Layout>, optional<bool>` instead.
- Change codegen so that all op registrations are wrapped into `hacky_wrapper_for_legacy_signatures`. This is added to all ops but is a no-op if the op doesn't take TensorOptions. This allows us in the future to just change a kernel signature from `TensorOptions` to the scattered version and have it work without having to touch codegen.
- Change codegen so that the frontend calls those operators with expanded arguments instead of with a `TensorOptions` object. This is required because now the kernels are written in this way.

This PR does not remove TensorOptions special cases from codegen, but instead it separates kernels from the codegen/frontend issues. After this, kernels can be worked on separately without having to touch codegen and codegen can be worked on without having to touch kernels.

Codegen diff: P133121032

Differential Revision: [D21581908](https://our.internmc.facebook.com/intern/diff/D21581908/)

[ghstack-poisoned]
This PR adds `use_c10_dispatcher: full` to ops taking `TensorOptions`. To allow this, since the c10 operator library doesn't know about `TensorOptions`, we need to register the operator kernels as `optional<ScalarType>, optional<Device>, optional<Layout>, optional<bool>` instead, and also call them this way.

Changes:
- Add `use_c10_dispatcher: full` to those ops
- Write hacky_wrapper_for_legacy_signatures which takes an old-style kernel (i.e. one written to take `TensorOptions`) an creates a wrapper kernel for it that takes the scattered `optional<ScalarType>, optional<Device>, optional<Layout>, optional<bool>` instead.
- Change codegen so that all op registrations are wrapped into `hacky_wrapper_for_legacy_signatures`. This is added to all ops but is a no-op if the op doesn't take TensorOptions. This allows us in the future to just change a kernel signature from `TensorOptions` to the scattered version and have it work without having to touch codegen.
- Change codegen so that the frontend calls those operators with expanded arguments instead of with a `TensorOptions` object. This is required because now the kernels are written in this way.

This PR does not remove TensorOptions special cases from codegen, but instead it separates kernels from the codegen/frontend issues. After this, kernels can be worked on separately without having to touch codegen and codegen can be worked on without having to touch kernels.

Codegen diff: P133121032

Differential Revision: [D21581908](https://our.internmc.facebook.com/intern/diff/D21581908/)

[ghstack-poisoned]
@smessmer smessmer requested review from bhosmer and ezyang June 18, 2020 01:17
Copy link
Contributor

@ailzhang ailzhang left a comment

Choose a reason for hiding this comment

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

Stamping as we have a fix for the XLA failure. Thanks!

This PR adds `use_c10_dispatcher: full` to ops taking `TensorOptions`. To allow this, since the c10 operator library doesn't know about `TensorOptions`, we need to register the operator kernels as `optional<ScalarType>, optional<Device>, optional<Layout>, optional<bool>` instead, and also call them this way.

Changes:
- Add `use_c10_dispatcher: full` to those ops
- Write hacky_wrapper_for_legacy_signatures which takes an old-style kernel (i.e. one written to take `TensorOptions`) an creates a wrapper kernel for it that takes the scattered `optional<ScalarType>, optional<Device>, optional<Layout>, optional<bool>` instead.
- Change codegen so that all op registrations are wrapped into `hacky_wrapper_for_legacy_signatures`. This is added to all ops but is a no-op if the op doesn't take TensorOptions. This allows us in the future to just change a kernel signature from `TensorOptions` to the scattered version and have it work without having to touch codegen.
- Change codegen so that the frontend calls those operators with expanded arguments instead of with a `TensorOptions` object. This is required because now the kernels are written in this way.

This PR does not remove TensorOptions special cases from codegen, but instead it separates kernels from the codegen/frontend issues. After this, kernels can be worked on separately without having to touch codegen and codegen can be worked on without having to touch kernels.

Codegen diff: P133121032

Differential Revision: [D21581908](https://our.internmc.facebook.com/intern/diff/D21581908/)

[ghstack-poisoned]
Copy link

@bhosmer bhosmer left a comment

Choose a reason for hiding this comment

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

Hey, made it down to native_functions.yaml, will resume in a bit - meanwhile a few actionable suggestions in line that I'd pitch pretty enthusiastically. :)

DEFAULT_FUNCTION_REGISTRATION = CodeTemplate("""\
m.impl("${unqual_operator_name_with_overload}", TORCH_FN(TypeDefault::${type_wrapper_name}));
m.impl("${unqual_operator_name_with_overload}",
c10::impl::hacky_wrapper_for_legacy_signatures(TORCH_FN(TypeDefault::${type_wrapper_name})));
Copy link

Choose a reason for hiding this comment

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

It's a bit of a bummer that our nice clean API has so quickly gotten encrusted with this shim, in particular to the extent these calls will serve as example API usage. Ergonomically it's kind of rough (especially since it might do nothing). Two ideas:

  1. teach the codegen to only include the wrapper when necessary. I realize this intrudes on the complete decoupling you were going for here, but I think it would be worth it - the API usage will be better exemplified both for legacy and non-legacy cases. I.e., I think the value of complete decoupling is outweighed by the extent to which it obscures the (evolving) relationship between registered and implemented signatures, and by the readability hit.

To pitch the change another way: we want registrations for kernels that are already in our desired final state to look like it.

  1. hide the wrapper behind TORCH_FN, or a macro that wraps TORCH_FN. I think this is less desirable since it simply hides everything, rather than clarifying when the wrapper is needed, but it would fix the readability issue.

We can teach the codegen when to emit the wrapper just by looking for tensor options in the signature, correct? If so, I'd suggest having a function needs_legacy_wrapper where any future triggering conditions would also go (per the comment header in above the metaprogramming for this)

m.impl_UNBOXED("aten::${op_name_with_overload_name}", ${function_name});
""")

FUNCTION_REGISTRATION = CodeTemplate("""\
Copy link

Choose a reason for hiding this comment

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

Same suggestion re making hacky_wrapper conditional. Could use the same central discriminant function to decide; this would actually reinforce the difference as a canonical part of codegen logic and clarify where/why it was necessary.

This PR adds `use_c10_dispatcher: full` to ops taking `TensorOptions`. To allow this, since the c10 operator library doesn't know about `TensorOptions`, we need to register the operator kernels as `optional<ScalarType>, optional<Device>, optional<Layout>, optional<bool>` instead, and also call them this way.

Changes:
- Add `use_c10_dispatcher: full` to those ops
- Write hacky_wrapper_for_legacy_signatures which takes an old-style kernel (i.e. one written to take `TensorOptions`) an creates a wrapper kernel for it that takes the scattered `optional<ScalarType>, optional<Device>, optional<Layout>, optional<bool>` instead.
- Change codegen so that all op registrations are wrapped into `hacky_wrapper_for_legacy_signatures`. This is added to all ops but is a no-op if the op doesn't take TensorOptions. This allows us in the future to just change a kernel signature from `TensorOptions` to the scattered version and have it work without having to touch codegen.
- Change codegen so that the frontend calls those operators with expanded arguments instead of with a `TensorOptions` object. This is required because now the kernels are written in this way.

This PR does not remove TensorOptions special cases from codegen, but instead it separates kernels from the codegen/frontend issues. After this, kernels can be worked on separately without having to touch codegen and codegen can be worked on without having to touch kernels.

Codegen diff: P133121032

Differential Revision: [D21581908](https://our.internmc.facebook.com/intern/diff/D21581908/)

[ghstack-poisoned]
This PR adds `use_c10_dispatcher: full` to ops taking `TensorOptions`. To allow this, since the c10 operator library doesn't know about `TensorOptions`, we need to register the operator kernels as `optional<ScalarType>, optional<Device>, optional<Layout>, optional<bool>` instead, and also call them this way.

Changes:
- Add `use_c10_dispatcher: full` to those ops
- Write hacky_wrapper_for_legacy_signatures which takes an old-style kernel (i.e. one written to take `TensorOptions`) an creates a wrapper kernel for it that takes the scattered `optional<ScalarType>, optional<Device>, optional<Layout>, optional<bool>` instead.
- Change codegen so that all op registrations are wrapped into `hacky_wrapper_for_legacy_signatures`. This is added to all ops but is a no-op if the op doesn't take TensorOptions. This allows us in the future to just change a kernel signature from `TensorOptions` to the scattered version and have it work without having to touch codegen.
- Change codegen so that the frontend calls those operators with expanded arguments instead of with a `TensorOptions` object. This is required because now the kernels are written in this way.

This PR does not remove TensorOptions special cases from codegen, but instead it separates kernels from the codegen/frontend issues. After this, kernels can be worked on separately without having to touch codegen and codegen can be worked on without having to touch kernels.

Codegen diff: P133121032

Differential Revision: [D21581908](https://our.internmc.facebook.com/intern/diff/D21581908/)

[ghstack-poisoned]
@smessmer smessmer requested a review from bhosmer June 19, 2020 22:33
Copy link

@bhosmer bhosmer left a comment

Choose a reason for hiding this comment

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

LG, a few things inline, mostly copy pasting, but the only major question is whether to conditionalize the hacky wrapper use in this PR or a followup - up to you 😁

This PR adds `use_c10_dispatcher: full` to ops taking `TensorOptions`. To allow this, since the c10 operator library doesn't know about `TensorOptions`, we need to register the operator kernels as `optional<ScalarType>, optional<Device>, optional<Layout>, optional<bool>` instead, and also call them this way.

Changes:
- Add `use_c10_dispatcher: full` to those ops
- Write hacky_wrapper_for_legacy_signatures which takes an old-style kernel (i.e. one written to take `TensorOptions`) an creates a wrapper kernel for it that takes the scattered `optional<ScalarType>, optional<Device>, optional<Layout>, optional<bool>` instead.
- Change codegen so that all op registrations are wrapped into `hacky_wrapper_for_legacy_signatures`. This is added to all ops but is a no-op if the op doesn't take TensorOptions. This allows us in the future to just change a kernel signature from `TensorOptions` to the scattered version and have it work without having to touch codegen.
- Change codegen so that the frontend calls those operators with expanded arguments instead of with a `TensorOptions` object. This is required because now the kernels are written in this way.

This PR does not remove TensorOptions special cases from codegen, but instead it separates kernels from the codegen/frontend issues. After this, kernels can be worked on separately without having to touch codegen and codegen can be worked on without having to touch kernels.

Codegen diff: P133121032

Differential Revision: [D21581908](https://our.internmc.facebook.com/intern/diff/D21581908/)

[ghstack-poisoned]
@smessmer smessmer mentioned this pull request Jun 20, 2020
smessmer added 5 commits June 22, 2020 17:16
This PR adds `use_c10_dispatcher: full` to ops taking `TensorOptions`. To allow this, since the c10 operator library doesn't know about `TensorOptions`, we need to register the operator kernels as `optional<ScalarType>, optional<Device>, optional<Layout>, optional<bool>` instead, and also call them this way.

Changes:
- Add `use_c10_dispatcher: full` to those ops
- Write hacky_wrapper_for_legacy_signatures which takes an old-style kernel (i.e. one written to take `TensorOptions`) an creates a wrapper kernel for it that takes the scattered `optional<ScalarType>, optional<Device>, optional<Layout>, optional<bool>` instead.
- Change codegen so that all op registrations are wrapped into `hacky_wrapper_for_legacy_signatures`. This is added to all ops but is a no-op if the op doesn't take TensorOptions. This allows us in the future to just change a kernel signature from `TensorOptions` to the scattered version and have it work without having to touch codegen.
- Change codegen so that the frontend calls those operators with expanded arguments instead of with a `TensorOptions` object. This is required because now the kernels are written in this way.

This PR does not remove TensorOptions special cases from codegen, but instead it separates kernels from the codegen/frontend issues. After this, kernels can be worked on separately without having to touch codegen and codegen can be worked on without having to touch kernels.

Codegen diff: P133121032

Differential Revision: [D21581908](https://our.internmc.facebook.com/intern/diff/D21581908/)

[ghstack-poisoned]
This PR adds `use_c10_dispatcher: full` to ops taking `TensorOptions`. To allow this, since the c10 operator library doesn't know about `TensorOptions`, we need to register the operator kernels as `optional<ScalarType>, optional<Device>, optional<Layout>, optional<bool>` instead, and also call them this way.

Changes:
- Add `use_c10_dispatcher: full` to those ops
- Write hacky_wrapper_for_legacy_signatures which takes an old-style kernel (i.e. one written to take `TensorOptions`) an creates a wrapper kernel for it that takes the scattered `optional<ScalarType>, optional<Device>, optional<Layout>, optional<bool>` instead.
- Change codegen so that all op registrations are wrapped into `hacky_wrapper_for_legacy_signatures`. This is added to all ops but is a no-op if the op doesn't take TensorOptions. This allows us in the future to just change a kernel signature from `TensorOptions` to the scattered version and have it work without having to touch codegen.
- Change codegen so that the frontend calls those operators with expanded arguments instead of with a `TensorOptions` object. This is required because now the kernels are written in this way.

This PR does not remove TensorOptions special cases from codegen, but instead it separates kernels from the codegen/frontend issues. After this, kernels can be worked on separately without having to touch codegen and codegen can be worked on without having to touch kernels.

Codegen diff: P133121032

Differential Revision: [D21581908](https://our.internmc.facebook.com/intern/diff/D21581908/)

[ghstack-poisoned]
This PR adds `use_c10_dispatcher: full` to ops taking `TensorOptions`. To allow this, since the c10 operator library doesn't know about `TensorOptions`, we need to register the operator kernels as `optional<ScalarType>, optional<Device>, optional<Layout>, optional<bool>` instead, and also call them this way.

Changes:
- Add `use_c10_dispatcher: full` to those ops
- Write hacky_wrapper_for_legacy_signatures which takes an old-style kernel (i.e. one written to take `TensorOptions`) an creates a wrapper kernel for it that takes the scattered `optional<ScalarType>, optional<Device>, optional<Layout>, optional<bool>` instead.
- Change codegen so that all op registrations are wrapped into `hacky_wrapper_for_legacy_signatures`. This is added to all ops but is a no-op if the op doesn't take TensorOptions. This allows us in the future to just change a kernel signature from `TensorOptions` to the scattered version and have it work without having to touch codegen.
- Change codegen so that the frontend calls those operators with expanded arguments instead of with a `TensorOptions` object. This is required because now the kernels are written in this way.

This PR does not remove TensorOptions special cases from codegen, but instead it separates kernels from the codegen/frontend issues. After this, kernels can be worked on separately without having to touch codegen and codegen can be worked on without having to touch kernels.

Codegen diff: P133121032

Differential Revision: [D21581908](https://our.internmc.facebook.com/intern/diff/D21581908/)

[ghstack-poisoned]
This PR adds `use_c10_dispatcher: full` to ops taking `TensorOptions`. To allow this, since the c10 operator library doesn't know about `TensorOptions`, we need to register the operator kernels as `optional<ScalarType>, optional<Device>, optional<Layout>, optional<bool>` instead, and also call them this way.

Changes:
- Add `use_c10_dispatcher: full` to those ops
- Write hacky_wrapper_for_legacy_signatures which takes an old-style kernel (i.e. one written to take `TensorOptions`) an creates a wrapper kernel for it that takes the scattered `optional<ScalarType>, optional<Device>, optional<Layout>, optional<bool>` instead.
- Change codegen so that all op registrations are wrapped into `hacky_wrapper_for_legacy_signatures`. This is added to all ops but is a no-op if the op doesn't take TensorOptions. This allows us in the future to just change a kernel signature from `TensorOptions` to the scattered version and have it work without having to touch codegen.
- Change codegen so that the frontend calls those operators with expanded arguments instead of with a `TensorOptions` object. This is required because now the kernels are written in this way.

This PR does not remove TensorOptions special cases from codegen, but instead it separates kernels from the codegen/frontend issues. After this, kernels can be worked on separately without having to touch codegen and codegen can be worked on without having to touch kernels.

Codegen diff: P133121032

Differential Revision: [D21581908](https://our.internmc.facebook.com/intern/diff/D21581908/)

[ghstack-poisoned]
This PR adds `use_c10_dispatcher: full` to ops taking `TensorOptions`. To allow this, since the c10 operator library doesn't know about `TensorOptions`, we need to register the operator kernels as `optional<ScalarType>, optional<Device>, optional<Layout>, optional<bool>` instead, and also call them this way.

Changes:
- Add `use_c10_dispatcher: full` to those ops
- Write hacky_wrapper_for_legacy_signatures which takes an old-style kernel (i.e. one written to take `TensorOptions`) an creates a wrapper kernel for it that takes the scattered `optional<ScalarType>, optional<Device>, optional<Layout>, optional<bool>` instead.
- Change codegen so that all op registrations are wrapped into `hacky_wrapper_for_legacy_signatures`. This is added to all ops but is a no-op if the op doesn't take TensorOptions. This allows us in the future to just change a kernel signature from `TensorOptions` to the scattered version and have it work without having to touch codegen.
- Change codegen so that the frontend calls those operators with expanded arguments instead of with a `TensorOptions` object. This is required because now the kernels are written in this way.

This PR does not remove TensorOptions special cases from codegen, but instead it separates kernels from the codegen/frontend issues. After this, kernels can be worked on separately without having to touch codegen and codegen can be worked on without having to touch kernels.

Codegen diff: P133121032

Differential Revision: [D21581908](https://our.internmc.facebook.com/intern/diff/D21581908/)

[ghstack-poisoned]
@facebook-github-bot
Copy link
Contributor

This pull request has been merged in b623bde.

@facebook-github-bot facebook-github-bot deleted the gh/smessmer/224/head branch June 27, 2020 14:16
using parameters_before_tensoroptions =
guts::typelist::take_t<gathered_parameter_types, tensoroptions_arg_index>;
using parameters_after_tensoroptions =
guts::typelist::drop_t<gathered_parameter_types, tensoroptions_arg_index + 1>;
Copy link
Contributor

Choose a reason for hiding this comment

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

Not gonna lie: I'm impressed this all works at all! Do you remember if there were any hidden bombshells, e.g., compiler bugs, you had to work around to get this working? (What are the buried skeletons?)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants