Fix torch.histc not checking min > max on cuda for int8 tensors (#139372)

Fixes #139360

86e6513c86/aten/src/ATen/native/cuda/SummaryOps.cu (L323-L324)

Assign `min` and `max` to with low-precision input_t variable `minvalue` and `maxvalue` cause wrong comparing result in following check in here:

86e6513c86/aten/src/ATen/native/cuda/SummaryOps.cu (L353)

![image](https://github.com/user-attachments/assets/0d5c87f4-3dc6-48bb-bcc8-b1803e7cd487)

Change type of `minvalue` and `maxvalue` to fix it, similar like in line:

86e6513c86/aten/src/ATen/native/cuda/SummaryOps.cu (L280-L282)

**Test Result**
```bash
$ pytest test/test_reductions.py -vv
```
![image](https://github.com/user-attachments/assets/6b5d0d48-ebc2-4a8c-85f4-dbad147c086c)

```bash
$ lintrunner
```
![image](https://github.com/user-attachments/assets/f97c2d6d-78ea-4439-a1ba-907bc9defad7)

Pull Request resolved: https://github.com/pytorch/pytorch/pull/139372
Approved by: https://github.com/eqy
This commit is contained in:
zeshengzong
2024-11-05 08:42:35 +00:00
committed by PyTorch MergeBot
parent 356fc41ae0
commit ffb7a08921
3 changed files with 29 additions and 3 deletions

View File

@ -320,8 +320,10 @@ Tensor _histc_cuda_template(
std::nullopt /* layout */,
DeviceType::CUDA,
std::nullopt /* pin_memory */);
input_t minvalue = min;
input_t maxvalue = max;
using bounds_t = at::acc_type<input_t, /*is_cuda=*/true>;
bounds_t minvalue = min;
bounds_t maxvalue = max;
if (min == max && self.numel() > 0) {
minvalue = *self.min().cpu().const_data_ptr<input_t>();
maxvalue = *self.max().cpu().const_data_ptr<input_t>();

View File

@ -3116,6 +3116,30 @@ class TestReductions(TestCase):
actual)
self.assertEqual(actual.dtype, dtype)
@dtypes(torch.uint8, torch.int8, torch.int, torch.long, torch.float, torch.double)
def test_histc_min_max_errors(self, device, dtype):
with self.assertRaisesRegex(RuntimeError, "max must be larger than min"):
torch.histc(torch.tensor([1., 2., 3.], dtype=dtype, device=device), bins=4, min=5, max=1)
@dtypes(torch.float, torch.double)
def test_histc_min_max_corner_cases(self, device, dtype):
actual = torch.histc(
torch.tensor([1., 2, 1], dtype=dtype, device=device),
bins=4, min=5, max=5)
self.assertEqual(
torch.tensor([2, 0, 0, 1], dtype=dtype, device=device),
actual)
@onlyCUDA
@dtypes(torch.uint8, torch.int8, torch.int, torch.long)
def test_histc_min_max_corner_cases_cuda(self, device, dtype):
actual = torch.histc(
torch.tensor([1., 2, 1], dtype=dtype, device=device),
bins=4, min=5, max=5)
self.assertEqual(
torch.tensor([2, 0, 0, 1], dtype=dtype, device=device),
actual)
"""
Runs torch.histogram and numpy.histogram on the specified input parameters
and asserts that their output is equal.

View File

@ -19375,7 +19375,7 @@ op_db: List[OpInfo] = [
)),
OpInfo('histc',
dtypes=floating_types_and(torch.bfloat16, torch.float16),
dtypesIfCUDA=floating_types_and(torch.int8, torch.int16, torch.int32, torch.int64),
dtypesIfCUDA=floating_types_and(torch.int8, torch.uint8, torch.int16, torch.int32, torch.int64),
sample_inputs_func=sample_inputs_histc,
supports_out=True,
supports_autograd=False,