Skip to content

Conversation

@ysiraichi
Copy link
Collaborator

@ysiraichi ysiraichi commented Apr 29, 2022

Fixes #76430

The Problem: opt_dtype wasn't being taken into consideration when checking whether the input dtype was either floating point or complex dtype.

The Solution: run those checks with the dtype returned by get_dtype_from_self(self, opt_dtype, true).

This fix restores the original behavior, before #61643. It also improves the error message so that the user better comprehends what happened. Finally, I also added 2 tests for ensuring the issue was fixed


Before

>>> a = torch.randint(0, 5, (5, 5), dtype=torch.int64)
>>> b = torch.tensor([], dtype=torch.float32)

>>> a.mean() # no dtype
RuntimeError: mean(): input dtype should be either floating point or complex dtypes. Got Long instead.

>>> a.mean(dtype=torch.float32) # with dtype
RuntimeError: mean(): input dtype should be either floating point or complex dtypes. Got Long instead.

>>> torch.mean(a, [], dtype=torch.float64, out=b) # with mismatching dtype and out dtype
RuntimeError: mean(): input dtype should be either floating point or complex dtypes. Got Long instead.

After

>>> a = torch.randint(0, 5, (5, 5), dtype=torch.int64)
>>> b = torch.tensor([], dtype=torch.float32)

>>> a.mean() # no dtype
RuntimeError: mean(): at least one of (i) the input dtype and (ii) the desired output dtype should be either floating point or complex. Got (i) Long and (ii) None instead.

>>> a.mean(dtype=torch.float32) # with dtype
tensor(1.6800)

>>> torch.mean(a, [], dtype=torch.float64, out=b) # with mismatching dtype and out dtype
RuntimeError: Expected out tensor to have dtype double, but got float instead

@facebook-github-bot
Copy link
Contributor

facebook-github-bot commented Apr 29, 2022

🔗 Helpful links

✅ No Failures (0 Pending)

As of commit 9d8ae5f (more details on the Dr. CI page):

Expand to see more

💚 💚 Looks good so far! There are no failures yet. 💚 💚


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.

@ysiraichi
Copy link
Collaborator Author

@ngimel suggested casting the input directly to a floating point tensor. But, since I wasn't sure what the output dtype should be (half, float, or double), I simply fixed it so as to match the old behavior.

@vadimkantorov
Copy link
Contributor

vadimkantorov commented Apr 29, 2022

about auto-casting integral tensor (and fixing #64897): I propose to auto-cast to torch.get_default_dtype()

For practical use-cases: computing accuracy by taking mean of booltensor and computing a mean value of [0, 255] uint8 images etc. For them upcasting to float32 might be sufficient

Copy link
Collaborator

Choose a reason for hiding this comment

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

Probably want to hide this computation in a conditional that checks the error conditions so we're not creating this string on every call

Copy link
Collaborator

Choose a reason for hiding this comment

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

I think we can model this as an ErrorInput for the mean OpInfo?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Same thing -- can we make this an ErrorInput?

@mruberry mruberry added the triaged This issue has been looked at a team member, and triaged and prioritized into an appropriate module label May 3, 2022
@ysiraichi
Copy link
Collaborator Author

about auto-casting integral tensor (and fixing #64897): I propose to auto-cast to torch.get_default_dtype()

I think that makes sense to me, and hopefully it is not too confusing.
Given torch.mean(t, [], dtype=opt_dtype):

t opt_dtype Output dtype
integral tensor None torch.get_default_dtype()
* floating or complex dtype opt_dtype
floating or complex tensor None t.dtype

@mruberry @ngimel
What do you think?
That said, I think it is better to leave it to a future PR.

@mruberry
Copy link
Collaborator

mruberry commented May 4, 2022

about auto-casting integral tensor (and fixing #64897): I propose to auto-cast to torch.get_default_dtype()

I think that makes sense to me, and hopefully it is not too confusing. Given torch.mean(t, [], dtype=opt_dtype):

t opt_dtype Output dtype
integral tensor None torch.get_default_dtype()

  • floating or complex dtype opt_dtype
    floating or complex tensor None t.dtype
    @mruberry @ngimel What do you think? That said, I think it is better to leave it to a future PR.

That looks correct to me, but I'll let @ngimel review this more thoroughly since she's been working closely with reductions recently

@vadimkantorov
Copy link
Contributor

For integral tensors one funny option may also be to do sum in int64 (or int32?) and then divide by the size - but maybe this might actually be slower and have worse dynamic range behavior than float

@ysiraichi
Copy link
Collaborator Author

@mruberry @ngimel
This is a friendly reminder. Do you have some time to take a look at this PR?
I think it is better to introduce the changes for supporting integral tensors in a separate PR (that's why I didn't implement them here).

Copy link
Collaborator

Choose a reason for hiding this comment

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

this is a misleading error message, e.g. if self dtype if float but dtype arg is integer, then it's and invalid combination (and you'll rightly error out), but error message wouldn't explain it.

@ysiraichi ysiraichi force-pushed the fix-mean-regression branch from 76074f7 to 52a2d4f Compare May 11, 2022 10:20
@ysiraichi
Copy link
Collaborator Author

@mruberry @ngimel
This is a friendly reminder. Do you have some time to take a look at this PR?

@ngimel
Copy link
Collaborator

ngimel commented May 15, 2022

@pytorchbot merge this

@github-actions
Copy link
Contributor

Hey @ysiraichi.
You've committed this PR, but it does not have both a 'release notes: ...' and 'topics: ...' label. Please add one of each to the PR. The 'release notes: ...' label should represent the part of PyTorch that this PR changes (fx, autograd, distributed, etc) and the 'topics: ...' label should represent the kind of PR it is (not user facing, new feature, bug fix, perf improvement, etc). The list of valid labels can be found here for the 'release notes: ...' and here for the 'topics: ...'.
For changes that are 'topic: not user facing' there is no need for a release notes label.

@ysiraichi ysiraichi added release notes: cpp release notes category topic: bug fixes topic category labels May 16, 2022
facebook-github-bot pushed a commit that referenced this pull request May 17, 2022
Summary:
Fixes #76430

**The Problem:** `opt_dtype` wasn't being taken into consideration when checking whether the input dtype was either floating point or complex dtype.

**The Solution:** run those checks with the dtype returned by `get_dtype_from_self(self, opt_dtype, true)`.

This fix restores the original behavior, before #61643. It also improves the error message so that the user better comprehends what happened. Finally, I also added 2 tests for ensuring the issue was fixed

-----
#### Before

```python
>>> a = torch.randint(0, 5, (5, 5), dtype=torch.int64)
>>> b = torch.tensor([], dtype=torch.float32)

>>> a.mean() # no dtype
RuntimeError: mean(): input dtype should be either floating point or complex dtypes. Got Long instead.

>>> a.mean(dtype=torch.float32) # with dtype
RuntimeError: mean(): input dtype should be either floating point or complex dtypes. Got Long instead.

>>> torch.mean(a, [], dtype=torch.float64, out=b) # with mismatching dtype and out dtype
RuntimeError: mean(): input dtype should be either floating point or complex dtypes. Got Long instead.
```

#### After

```python
>>> a = torch.randint(0, 5, (5, 5), dtype=torch.int64)
>>> b = torch.tensor([], dtype=torch.float32)

>>> a.mean() # no dtype
RuntimeError: mean(): at least one of (i) the input dtype and (ii) the desired output dtype should be either floating point or complex. Got (i) Long and (ii) None instead.

>>> a.mean(dtype=torch.float32) # with dtype
tensor(1.6800)

>>> torch.mean(a, [], dtype=torch.float64, out=b) # with mismatching dtype and out dtype
RuntimeError: Expected out tensor to have dtype double, but got float instead
```

Pull Request resolved: #76584
Approved by: https://github.com/ngimel

Test Plan: contbuild & OSS CI, see https://hud.pytorch.org/commit/pytorch/pytorch/459e10f4465fd5a75e6dea96597b427feae71e42

Reviewed By: atalman

Differential Revision: D36412508

Pulled By: atalman

fbshipit-source-id: 7acfec825bc3efaaf62e124ddc24a1034fc6792e
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cla signed Merged open source release notes: cpp release notes category topic: bug fixes topic category triaged This issue has been looked at a team member, and triaged and prioritized into an appropriate module

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[regression] int_tensor.mean(dtype=float32) should work

7 participants