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

register tensor and PIL kernel the same way as datapoints #7797

Merged
merged 14 commits into from
Aug 7, 2023

Conversation

pmeier
Copy link
Collaborator

@pmeier pmeier commented Aug 2, 2023

Follow-up to #7747 and prerequisite for 2./3. in #7747 (comment).

cc @vfdev-5

@pytorch-bot
Copy link

pytorch-bot bot commented Aug 2, 2023

🔗 Helpful Links

🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/vision/7797

Note: Links to docs will display an error until the docs builds have been completed.

❌ 32 New Failures

As of commit 4068251:

NEW FAILURES - The following jobs have failed:

This comment was automatically generated by Dr. CI and updates every 15 minutes.

@@ -449,6 +394,9 @@ def test_datapoint_output_type(self, info, args_kwargs):

assert isinstance(output, type(datapoint))

if isinstance(datapoint, datapoints.BoundingBoxes) and info.dispatcher is not F.convert_format_bounding_boxes:
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Since this test is part of the legacy framework, I was to lazy to handle this more elegantly.

test/test_transforms_v2_refactored.py Show resolved Hide resolved
def check_dispatcher(
dispatcher,
# TODO: remove this parameter
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

We no longer need this parameter. However, we previously parametrized over it together with the function to create the input. Thus, removing it is chore that I'll deal with after release. It doesn't have any effect on the runtime, because the number of tests stays exactly the same after this parameter is removed.

torchvision/transforms/v2/functional/_utils.py Outdated Show resolved Hide resolved
@pmeier
Copy link
Collaborator Author

pmeier commented Aug 2, 2023

for registered_cls, kernel in registry.items():
if issubclass(datapoint_cls, registered_cls):
return kernel

as part of _get_kernel creates an issue when we register a kernel for torch.Tensor. Imagine I have class MyDatapoint(Datapoint). With the current state, I would expect it being passed through if I don't register anything for it. However, since issubclass(MyDatapoint, torch.Tensor), we select the plain tensor kernel instead and try to transform it. This is what causing the failures on prototype, since we still have class Label(Datapoint) there.

The reason why I think this loop is valuable in general rather than just having the exact type match

if datapoint_cls in registry:
return registry[datapoint_cls]

is explained in #7747 (comment).

@_register_kernel_internal(rgb_to_grayscale, datapoints.Image)
def rgb_to_grayscale_image_tensor(image: torch.Tensor, num_output_channels: int = 1) -> torch.Tensor:
if num_output_channels not in (1, 3):
Copy link
Collaborator Author

@pmeier pmeier Aug 2, 2023

Choose a reason for hiding this comment

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

For some reason, this previously was done on the dispatcher rather than in the kernel. I moved it to the kernel here and the same for the PIL kernel below.

torchvision/transforms/v2/functional/_color.py Outdated Show resolved Hide resolved
Comment on lines +291 to +292
@_register_kernel_internal(resize, PIL.Image.Image)
def _resize_image_pil_dispatch(
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 needed to extract this out due to the warning.

torchvision/transforms/v2/functional/_geometry.py Outdated Show resolved Hide resolved
@pmeier
Copy link
Collaborator Author

pmeier commented Aug 3, 2023

#7797 (comment) is resolved now with the following rules:

  1. Users are not allowed to register anything but datapoint subclasses with @register_kernel. Our decorator @_register_kernel_internal does not have this limitation allowing us to register kernels for PIL.Image.Image and torch.Tensor.
  2. When retrieving a kernel with _get_kernel
    1. We first check for an exact type match. For datapoints this is still just a performance improvement, while for PIL.Image.Image and torch.Tensor this is the only way to retrieve kernels.
    2. If there is no exact match and the input is a datapoint, we move up its MRO looking for a kernel registered for a superclass. This is for the class MyImage(datapoints.Image) use case, but in theory also supports retrieving the kernel for datapoints.Image if it weren't for the exact type match above. In case we don't find anything, we return a no-op kernel. This is only temporary until we can go for 2. / 3. in refactor Datapoint dispatch mechanism #7747 (comment) and only happens for datapoints.
    3. If there is no exact match and the input is not a datapoint, we error out.

test/test_transforms_v2_refactored.py Outdated Show resolved Hide resolved
test/test_transforms_v2_refactored.py Outdated Show resolved Hide resolved
test/test_transforms_v2_refactored.py Outdated Show resolved Hide resolved
test/test_transforms_v2_refactored.py Outdated Show resolved Hide resolved
test/test_transforms_v2_refactored.py Outdated Show resolved Hide resolved
test/test_transforms_v2_refactored.py Outdated Show resolved Hide resolved
test/test_transforms_v2_refactored.py Outdated Show resolved Hide resolved
Copy link
Member

@NicolasHug NicolasHug left a comment

Choose a reason for hiding this comment

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

Took a look at the utils and a few kernels, LGTM.

I'll approve so we don't have to go through another review round. I hope we can make the tests (comments above) a bit more trivial, but this is non-blocking and can be addressed later

Thanks a lot for all this Philip, I'm sure it wasn't fun shuffling so much code, but it's great to see that a lot of the clutter was removed from the dispatchers logic

@pmeier pmeier merged commit 2030d20 into pytorch:main Aug 7, 2023
10 of 39 checks passed
@pmeier pmeier deleted the register-tensor-pil branch August 7, 2023 07:46
facebook-github-bot pushed a commit that referenced this pull request Aug 25, 2023
…7797)

Summary: Co-authored-by: Nicolas Hug <contact@nicolas-hug.com>

Reviewed By: matteobettini

Differential Revision: D48642326

fbshipit-source-id: ee9cd9d5d32b1c4433554763812e44fb6c189fc9
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.

None yet

3 participants