Add scale option to ToDtype. Remove ConvertDtype.#7759
Add scale option to ToDtype. Remove ConvertDtype.#7759NicolasHug merged 14 commits intopytorch:mainfrom
Conversation
pmeier
left a comment
There was a problem hiding this comment.
I have a bunch of comments, but overall looks solid.
|
|
||
| def convert_dtype_image_tensor(image: torch.Tensor, dtype: torch.dtype = torch.float) -> torch.Tensor: | ||
| def to_dtype_image_tensor(image: torch.Tensor, dtype: torch.dtype = torch.float, scale: bool = False) -> torch.Tensor: | ||
| if not scale: |
There was a problem hiding this comment.
Should this come after the dtype check? Functionally, this is a no-op here in case image.dtype == dtype, but it is still an unnecessary call.
if image.dtype == dtype:
return image
elif not scale:
return image.to(dtype)makes the behavior a little more clear and should be minimally more performant.
There was a problem hiding this comment.
I'll do it but TBH I don't really follow the reasoning behind the change
There was a problem hiding this comment.
The elif part actually adds confusion to me because it suggests these 2 blocks are related when in reality they're really not
There was a problem hiding this comment.
Re-reading the original implementation: I was wrong. Since we already return'ed in both branches, this should have no effect on the performance. Thus, feel free to revert to what you had.
Still, I would put the dtype check at the top, because that is the "more important" one. Again, just style / personal preference. Ignore if you feel different.
The
elifpart actually adds confusion to me because it suggests these 2 blocks are related when in reality they're really not
Fair enough. Happy with a second if as well.
| check_cuda_vs_cpu=True, | ||
| check_scripted_vs_eager=True, | ||
| check_batched_vs_unbatched=True, | ||
| expect_same_dtype=True, |
There was a problem hiding this comment.
Not against it, but are we expecting more kernels to set this to False?
There was a problem hiding this comment.
I don't think so (more precisely: I don't know). We still want the rest of the checks to be done for ToDtype though. Is there a better way than to add a parameter?
There was a problem hiding this comment.
Not really. Since this will be the only the kernel that ever needs this, we could implement a custom check_kernel inside the test class. Basically copy-pasting the current function, but add the new parameter as well as stripping everything that is more generic, but not needed in this specific case. This would keep the check_kernel signature clean since it already has quite a few parameters.
Kinda torn on this. Up to you. I'm ok with both.
There was a problem hiding this comment.
I have a slight preference for adding the parameter, because otherwise we'd have to change both implementation of check_kernel if we ever needed to update it.
(looks like I'm advocating for this single entry point after all :p )
| def __init__(self, dtype: Union[torch.dtype, Dict[Type, Optional[torch.dtype]]], scale: bool = False) -> None: | ||
| super().__init__() | ||
| if not isinstance(dtype, dict): | ||
| dtype = _get_defaultdict(dtype) |
There was a problem hiding this comment.
Removing this behaviour we would like to go away from defaultdict(lambda: dtype) ?
There was a problem hiding this comment.
Yes, this is one of the goals #7756 (comment). It basically just gets replaced by {"others": dtype}:
- no need to know what a defaultdict is
- no need to import defaultdict
- no need to know what a lambda is
- no need to understand how defaultdict and lambda interact
There was a problem hiding this comment.
But should not this be done in a separate PR and everywhere it is used ?
There was a problem hiding this comment.
If this gets accepted here I was going to submit a follow-up PR to do the same changes for the fill parameters (which is probably much more work). Are there other places where this pattern is used?
There was a problem hiding this comment.
OK, sounds good to me.
PermuteDimensions, TransposeDimensions and _setup_fill_arg
Co-authored-by: vfdev <vfdev.5@gmail.com>
| @pytest.mark.parametrize("output_dtype", [torch.float32, torch.float64, torch.uint8]) | ||
| @pytest.mark.parametrize("device", cpu_and_cuda()) | ||
| @pytest.mark.parametrize("scale", (True, False)) | ||
| @pytest.mark.parametrize("as_dict", (True, False)) |
There was a problem hiding this comment.
I added this because when the dtype parameters isn't a dict and when the input is a single bbox or a single mask (as is the case here), the input just gets passed-through. I'm converting the dtype into a dict so that we also test the rest of the code-paths for those single bboxes and masks. Not incredibly critical, just for coverage.
pmeier
left a comment
There was a problem hiding this comment.
Some comments, but nothing blocking. LGTM if CI is green. Thanks Nicolas!
| check_cuda_vs_cpu=True, | ||
| check_scripted_vs_eager=True, | ||
| check_batched_vs_unbatched=True, | ||
| expect_same_dtype=True, |
There was a problem hiding this comment.
Not really. Since this will be the only the kernel that ever needs this, we could implement a custom check_kernel inside the test class. Basically copy-pasting the current function, but add the new parameter as well as stripping everything that is more generic, but not needed in this specific case. This would keep the check_kernel signature clean since it already has quite a few parameters.
Kinda torn on this. Up to you. I'm ok with both.
| return inpt.max() <= 1 | ||
|
|
||
| H, W = 10, 10 | ||
| sample = { |
There was a problem hiding this comment.
Should we also throw a video in there?
There was a problem hiding this comment.
We do (from the parametrization), although I kept img as a name which I agree is confusing. I'll use inpt instead
| make_video, | ||
| ), | ||
| ) | ||
| def test_behaviour(self, make_input): |
There was a problem hiding this comment.
This test is huge. Should we maybe split it into multiple ones?
Co-authored-by: Philip Meier <github.pmeier@posteo.de>
|
Tests are green in 92f2588 except for the linter which I just fixed. Merging, thanks for the reviews! |
|
Hey @NicolasHug! You merged this PR, but no labels were added. The list of valid labels is available at https://github.com/pytorch/vision/blob/main/.github/process_commit.py |
Reviewed By: matteobettini Differential Revision: D48642282 fbshipit-source-id: 95a2eea16407f17e1ebeb386cd5e2618a105450f Co-authored-by: vfdev <vfdev.5@gmail.com> Co-authored-by: Philip Meier <github.pmeier@posteo.de>
Closes #7756
this PR:
scaleparameter to ToDtype, which only affects images or videosconvert_.*and replace withto_dtype*dispatchers / kernels.ToDtype(torch.float32)i.e. thedtypeparameter is just a dtype, not a dict, we only convert images and videos - this is for BC with ConvertImageDtype and reduces adoption friction(I may have removed too much stuff on the existing tests, we'll see with the CI)
cc @vfdev-5