Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix _empty_per_channel_affine_quantized to be less hacky #26243

Closed
wants to merge 4 commits into from

Conversation

dzhulgakov
Copy link
Collaborator

@dzhulgakov dzhulgakov commented Sep 14, 2019

Stack from ghstack:

This is an attempt to fix _empty_per_channel_affine_quantized to be more sane. It's a factory function that nevertheless receives a Tensor argument and it throws the codegen off course.

Before people did a hacky workaround of appending _like to the function name to trick codegen, it also required non-natural argument order.

This PR explicitly allows to override the 'category' of the function to make codegen do the right thing. Now name and the argument order (in C++) make more sense.

Gist with changes to codegen: https://gist.github.com/dzhulgakov/87050fcf7527730bea6483600f8c4897 (from ./tools/git_add_generated_dirs.sh)

Differential Revision: D17443221

@pytorchbot pytorchbot added module: docs Related to our documentation, both in docs/ and docblocks module: internals Related to internal abstractions in c10 and ATen module: operators module: pybind Related to our Python bindings / interactions with other Python libraries oncall: quantization Quantization support in PyTorch labels Sep 14, 2019
dzhulgakov pushed a commit that referenced this pull request Sep 14, 2019
ghstack-source-id: f579191e44b8176b7271d10e421d05edc156b35a
Pull Request resolved: #26243
@dzhulgakov dzhulgakov changed the title _like fix 1 Fix _empty_per_channel_affine_quantized to be less hacky Sep 14, 2019
dzhulgakov pushed a commit that referenced this pull request Sep 17, 2019
ghstack-source-id: 3d06e3059d294332506ed7d943ebb18f395e6ffe
Pull Request resolved: #26243
@jamesr66a
Copy link
Collaborator

Can you post a diff of the codegen'ed files before and after this change?

@@ -99,7 +99,9 @@ signature.
Functions with no tensor inputs are called *factory functions*, and
are handled specially by code generation. If your function is behaving
differently than another example, check first and see if one is a
factory while another is not.
factory while another is not. In some rare cases, factory function might have a
tensor argument. In this case it'd be marked with 'category_override: factory'
Copy link
Collaborator

Choose a reason for hiding this comment

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

it'd be marked -> mark it

@@ -142,10 +142,10 @@ Tensor per_channel_affine_qtensor_cpu(
const Tensor& scales,
const Tensor& zero_points,
IntArrayRef axis) {
Tensor dst = at::_empty_per_channel_affine_quantized_like(
Tensor dst = at::_empty_per_channel_affine_quantized(
Copy link
Contributor

Choose a reason for hiding this comment

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

what should be the order of arguments?
should we put size in the end so it is closer to options?

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 think sizes should be first - similarly to how we do it for at::full or at::rand

Copy link
Contributor

@raghuramank100 raghuramank100 left a comment

Choose a reason for hiding this comment

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

Looks good to me, will let folks more familiar with this part of the code approve.

Copy link
Contributor

@gchanan gchanan left a comment

Choose a reason for hiding this comment

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

ya I'd like to see the codegen changes.

I think the original issue is we didn't know how to dispatch these things. Because we usually dispatch based on the tensor argument but in this case, I'm not even sure what we were dispatching on. I also think @ezyang's recent multi dispatch changes might have affected this, because I know he was changing how "new" functions worked.

@dzhulgakov
Copy link
Collaborator Author

dzhulgakov commented Sep 19, 2019

Gist with changes to codegen: https://gist.github.com/dzhulgakov/87050fcf7527730bea6483600f8c4897 (from ./tools/git_add_generated_dirs.sh)

The changes look good to me. The only material changes are in VariableType argument passing and they seem correct (before we were inheriting device and scalar type from quantizer arguments and it doesn't make sense.

@ezyang
Copy link
Contributor

ezyang commented Sep 19, 2019

The conflict with my changes looks very mild and I can help resolve the changes if I land before this one. (Or if you land before me, I can fix it in my patch, but I'm landing right now and hope it will work this time ;)

This is an attempt to fix _empty_per_channel_affine_quantized to be more sane. It's a factory function that nevertheless receives a Tensor argument and it throws the codegen off course.

Before people did a hacky workaround of appending _like to the function name to trick codegen, it also required non-natural argument order.

This PR explicitly allows to override the 'category' of the function to make codegen do the right thing. Now name and the argument order (in C++) make more sense.

Gist with changes to codegen: https://gist.github.com/dzhulgakov/87050fcf7527730bea6483600f8c4897 (from ./tools/git_add_generated_dirs.sh)

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

[ghstack-poisoned]
dzhulgakov pushed a commit that referenced this pull request Sep 23, 2019
ghstack-source-id: 979c1bf9e97751ac04e3bfce45127bf897e1f8e8
Pull Request resolved: #26243
This is an attempt to fix _empty_per_channel_affine_quantized to be more sane. It's a factory function that nevertheless receives a Tensor argument and it throws the codegen off course.

Before people did a hacky workaround of appending _like to the function name to trick codegen, it also required non-natural argument order.

This PR explicitly allows to override the 'category' of the function to make codegen do the right thing. Now name and the argument order (in C++) make more sense.

Gist with changes to codegen: https://gist.github.com/dzhulgakov/87050fcf7527730bea6483600f8c4897 (from ./tools/git_add_generated_dirs.sh)

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

[ghstack-poisoned]
@pytorchbot pytorchbot added the oncall: jit Add this issue/PR to JIT oncall triage queue label Sep 23, 2019
dzhulgakov pushed a commit that referenced this pull request Sep 23, 2019
ghstack-source-id: 799516945cff58c03cc8f0b213a5cc40ae93e8a1
Pull Request resolved: #26243
@@ -593,12 +593,13 @@ def get_python_binding_arguments(declaration):
# produce a compile-time error that is obvious
has_tensor_return = True

is_like_function = name.endswith('_like')
category = declaration['category_override']
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: I would expect that "category" is the correct category at the end of this block, might be worth calling this category_override, which is how it's used.

@@ -991,7 +991,9 @@
dispatch:
QuantizedCPU: empty_affine_quantized_cpu

- func: _empty_per_channel_affine_quantized_like(Tensor self, Tensor zero_points, int[] size, int[] axis, *, ScalarType? dtype=None, Layout? layout=None, Device? device=None, bool? pin_memory=None, MemoryFormat? memory_format=contiguous_format) -> Tensor
# it's a factory function receiving a tensor argument, thus overriding explicitly
- func: _empty_per_channel_affine_quantized(int[] size, *, Tensor scales, Tensor zero_points, int[] axis, ScalarType? dtype=None, Layout? layout=None, Device? device=None, bool? pin_memory=None, MemoryFormat? memory_format=contiguous_format) -> Tensor
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this is all a pre-existing issue with TensorOptions, but I don't see how the dispatch makes sense here.

For example, if I don't specify a dtype, I won't try to dispatch to QuantizedCPU and presumably I'll just get some crappy error message about _empty_per_channel_affine_quantized not being implemented for CPU backend.

But really...dtype is not optional. So maybe we don't want to do anything until @izdeby breaks apart TensorOptions, but it seems reasonable to provide a CPU overload and to give a real error message here.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Good idea, let me fix the error message.Btw, it applies to other qtensor factory functions too

This is an attempt to fix _empty_per_channel_affine_quantized to be more sane. It's a factory function that nevertheless receives a Tensor argument and it throws the codegen off course.

Before people did a hacky workaround of appending _like to the function name to trick codegen, it also required non-natural argument order.

This PR explicitly allows to override the 'category' of the function to make codegen do the right thing. Now name and the argument order (in C++) make more sense.

Gist with changes to codegen: https://gist.github.com/dzhulgakov/87050fcf7527730bea6483600f8c4897 (from ./tools/git_add_generated_dirs.sh)

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

[ghstack-poisoned]
This is an attempt to fix _empty_per_channel_affine_quantized to be more sane. It's a factory function that nevertheless receives a Tensor argument and it throws the codegen off course.

Before people did a hacky workaround of appending _like to the function name to trick codegen, it also required non-natural argument order.

This PR explicitly allows to override the 'category' of the function to make codegen do the right thing. Now name and the argument order (in C++) make more sense.

Gist with changes to codegen: https://gist.github.com/dzhulgakov/87050fcf7527730bea6483600f8c4897 (from ./tools/git_add_generated_dirs.sh)

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

[ghstack-poisoned]
zdevito pushed a commit to zdevito/ATen that referenced this pull request Sep 24, 2019
Summary:
Pull Request resolved: pytorch/pytorch#26243

This is an attempt to fix _empty_per_channel_affine_quantized to be more sane. It's a factory function that nevertheless receives a Tensor argument and it throws the codegen off course.

Before people did a hacky workaround of appending _like to the function name to trick codegen, it also required non-natural argument order.

This PR explicitly allows to override the 'category' of the function to make codegen do the right thing. Now name and the argument order (in C++) make more sense.

Test Plan: Imported from OSS

Differential Revision: D17443221

Pulled By: dzhulgakov

fbshipit-source-id: c98c1c74473d8cbf637f511d26ceb949d8ae2a1a
@facebook-github-bot
Copy link
Contributor

@dzhulgakov merged this pull request in 9aad4d7.

@facebook-github-bot facebook-github-bot deleted the gh/dzhulgakov/4/head branch October 28, 2019 22:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Merged module: docs Related to our documentation, both in docs/ and docblocks module: internals Related to internal abstractions in c10 and ATen module: pybind Related to our Python bindings / interactions with other Python libraries oncall: jit Add this issue/PR to JIT oncall triage queue oncall: quantization Quantization support in PyTorch
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

9 participants