已合并
Update test_reductions of pt2.4 #12189
AtomGit-Bot创建于 2024年6月4日
Update test_reductions of pt2.4 #12189
已合并
从refs/pull/12189/head合入到master
共 1 个文件变更+89-24
| @@ -1115,6 +1115,13 @@ class TestReductions(TestCase): | |||
| 1115 | self.assertTrue(x.all()) | 1115 | self.assertTrue(x.all()) |
| 1116 | self.assertFalse(x.any()) | 1116 | self.assertFalse(x.any()) |
| 1117 | 1117 | ||
| 1118 | + def test_all_issue117215(self, device): | ||
| 1119 | + info = torch.iinfo(torch.uint8) | ||
| 1120 | + a = torch.randint(info.min, info.max, (73, 11, 3, 17), dtype=torch.uint8) | ||
| 1121 | + b = torch.all(a, dim=0) | ||
| 1122 | + c = a.to(torch.bool).all(dim=0) | ||
| 1123 | + self.assertEqual(torch.ne(b, c).sum(), 0) | ||
| 1124 | + | ||
| 1118 | 1125 | ||
| 1119 | 1126 | ||
| 1120 | def test_max_with_inf(self, device, dtype): | 1127 | def test_max_with_inf(self, device, dtype): |
| @@ -1335,6 +1342,52 @@ class TestReductions(TestCase): | |||
| 1335 | tensor = tensor.unsqueeze(1) | 1342 | tensor = tensor.unsqueeze(1) |
| 1336 | self.assertEqual(tensor.var(0), 0.03125) | 1343 | self.assertEqual(tensor.var(0), 0.03125) |
| 1337 | 1344 | ||
| 1345 | + | ||
| 1346 | + | ||
| 1347 | + def test_sum_noncontig_lowp(self, device, dtype) -> None: | ||
| 1348 | + dim_sequences = { | ||
| 1349 | + 2: [0, 1], | ||
| 1350 | + 3: [0, 1, 2], | ||
| 1351 | + 4: [0, 1, 2, 3], | ||
| 1352 | + 5: [0, 1, 2, 3, 4], | ||
| 1353 | + } | ||
| 1354 | + | ||
| 1355 | + # pylint:disable=inconsistent-return-statements | ||
| 1356 | + def create_noncontig_inputs(x, ndim): | ||
| 1357 | + if ndim == 2: | ||
| 1358 | + return x[::2, ::2] | ||
| 1359 | + elif ndim == 3: | ||
| 1360 | + return x[::2, ::2, ::2] | ||
| 1361 | + elif ndim == 4: | ||
| 1362 | + return x[::2, ::2, ::2, ::2] | ||
| 1363 | + elif ndim == 5: | ||
| 1364 | + return x[::2, ::2, ::2, ::2, ::2] | ||
| 1365 | + | ||
| 1366 | + def helper(self, shape, reduce_dims, device, dtype): | ||
| 1367 | + # pylint:disable=get-dict-value-exception | ||
| 1368 | + for permute_list in list(permutations(dim_sequences[len(shape)], len(shape))): | ||
| 1369 | + x = torch.ones(shape, device=device, dtype=dtype) | ||
| 1370 | + x = create_noncontig_inputs(x, len(shape)) | ||
| 1371 | + x_trans = x.permute(permute_list) | ||
| 1372 | + x_sum = torch.sum(x_trans, reduce_dims) | ||
| 1373 | + x_trans_ref = x_trans.float() | ||
| 1374 | + x_sum_ref = torch.sum(x_trans_ref, reduce_dims) | ||
| 1375 | + self.assertEqual(x_sum, x_sum_ref.to(dtype=dtype)) | ||
| 1376 | + | ||
| 1377 | + shapes = [ | ||
| 1378 | + (50, 50), | ||
| 1379 | + (50, 50, 50), | ||
| 1380 | + (10, 50, 30, 30), | ||
| 1381 | + (10, 5, 10, 50, 7), | ||
| 1382 | + ] | ||
| 1383 | + | ||
| 1384 | + for shape in shapes: | ||
| 1385 | + for i in range(1, len(shape) + 1): | ||
| 1386 | + # pylint:disable=get-dict-value-exception | ||
| 1387 | + reduce_dims = list(combinations(dim_sequences[len(shape)], i)) | ||
| 1388 | + for reduce_dim in reduce_dims: | ||
| 1389 | + helper(self, shape, reduce_dim, device, dtype) | ||
| 1390 | + | ||
| 1338 | 1391 | ||
| 1339 | 1392 | ||
| 1340 | def test_sum_all(self, device, dtype) -> None: | 1393 | def test_sum_all(self, device, dtype) -> None: |
| @@ -1352,7 +1405,7 @@ class TestReductions(TestCase): | |||
| 1352 | def _test_memory_format_transformations(self, device, input_generator_fn, transformation_fn, | 1405 | def _test_memory_format_transformations(self, device, input_generator_fn, transformation_fn, |
| 1353 | memory_format, compare_data=True, default_is_preserve=False): | 1406 | memory_format, compare_data=True, default_is_preserve=False): |
| 1354 | 1407 | ||
| 1355 | - assert(memory_format == torch.channels_last or memory_format == torch.channels_last_3d) | 1408 | + assert memory_format == torch.channels_last or memory_format == torch.channels_last_3d |
| 1356 | 1409 | ||
| 1357 | # xc is a channels last tensor | 1410 | # xc is a channels last tensor |
| 1358 | xc = input_generator_fn(device) | 1411 | xc = input_generator_fn(device) |
| @@ -1649,43 +1702,49 @@ class TestReductions(TestCase): | |||
| 1649 | self._test_reduction_function_with_numpy(torch.count_nonzero, np.count_nonzero, device, dtype) | 1702 | self._test_reduction_function_with_numpy(torch.count_nonzero, np.count_nonzero, device, dtype) |
| 1650 | self._test_reduction_function_with_numpy(torch.count_nonzero, np.count_nonzero, device, dtype, True) | 1703 | self._test_reduction_function_with_numpy(torch.count_nonzero, np.count_nonzero, device, dtype, True) |
| 1651 | 1704 | ||
| 1705 | + def _get_relaxed_tolerances_for(self, dtype): | ||
| 1706 | + if dtype == torch.float16: | ||
| 1707 | + atol = 0.4 | ||
| 1708 | + rtol = 1e-2 | ||
| 1709 | + elif dtype == torch.float32: | ||
| 1710 | + atol = 7e-05 | ||
| 1711 | + rtol = 3e-06 | ||
| 1712 | + else: | ||
| 1713 | + # Default values | ||
| 1714 | + atol = None | ||
| 1715 | + rtol = None | ||
| 1716 | + return atol, rtol | ||
| 1717 | + | ||
| 1652 | def _test_sum_reduction_vs_numpy(self, torch_fn, np_fn, device, dtype, with_keepdim=False, with_extremal=False): | 1718 | def _test_sum_reduction_vs_numpy(self, torch_fn, np_fn, device, dtype, with_keepdim=False, with_extremal=False): |
| 1653 | def is_integral(dtype): | 1719 | def is_integral(dtype): |
| 1654 | return dtype in integral_types() | 1720 | return dtype in integral_types() |
| 1655 | 1721 | ||
| 1722 | + exact_dtype = True | ||
| 1656 | # On Windows CI, the current version of `numpy` promotes all lower integers | 1723 | # On Windows CI, the current version of `numpy` promotes all lower integers |
| 1657 | # dtypes to int32 while `torch` promotes them to int64. Hence we skip on checking | 1724 | # dtypes to int32 while `torch` promotes them to int64. Hence we skip on checking |
| 1658 | # the exact dtype. | 1725 | # the exact dtype. |
| 1659 | - exact_dtype = False if (IS_WINDOWS and is_integral(dtype)) else True | 1726 | + if IS_WINDOWS and is_integral(dtype): |
| 1660 | - | 1727 | + exact_dtype = False |
| 1728 | + # For uint8, numpy promotes to uint64 while torch promotes to int64. | ||
| 1729 | + # So we must skip this as well. | ||
| 1661 | if dtype == torch.uint8: | 1730 | if dtype == torch.uint8: |
| 1662 | - with self.assertRaises(TypeError): | 1731 | + exact_dtype = False |
| 1663 | - self._test_reduction_function_with_numpy(torch_fn, np_fn, device, dtype, with_extremal=with_extremal) | 1732 | + |
| 1664 | - else: | 1733 | + # Investigate why the output is not close to numpy. |
| 1665 | - # Investigate why the output is not close to numpy. | 1734 | + atol, rtol = self._get_relaxed_tolerances_for(dtype) |
| 1666 | - if dtype == torch.float16: | ||
| 1667 | - atol = 0.4 | ||
| 1668 | - rtol = 1e-2 | ||
| 1669 | - elif dtype == torch.float32: | ||
| 1670 | - atol = 7e-05 | ||
| 1671 | - rtol = 3e-06 | ||
| 1672 | - else: | ||
| 1673 | - # Default values | ||
| 1674 | - atol = None | ||
| 1675 | - rtol = None | ||
| 1676 | - self._test_reduction_function_with_numpy(torch_fn, np_fn, device, dtype, | ||
| 1677 | - atol=atol, rtol=rtol, exact_dtype=exact_dtype, | ||
| 1678 | - with_keepdim=with_keepdim, with_extremal=with_extremal) | ||
| 1679 | 1735 | ||
| 1680 | - | 1736 | + self._test_reduction_function_with_numpy(torch_fn, np_fn, device, dtype, |
| 1681 | - @dtypes(*all_types_and(torch.half)) | 1737 | + atol=atol, rtol=rtol, exact_dtype=exact_dtype, |
| 1738 | + with_keepdim=with_keepdim, with_extremal=with_extremal) | ||
| 1739 | + | ||
| 1740 | + | ||
| 1682 | def test_sum_vs_numpy(self, device, dtype): | 1741 | def test_sum_vs_numpy(self, device, dtype): |
| 1683 | self._test_sum_reduction_vs_numpy(torch.sum, np.sum, device, dtype) | 1742 | self._test_sum_reduction_vs_numpy(torch.sum, np.sum, device, dtype) |
| 1684 | self._test_sum_reduction_vs_numpy(torch.sum, np.sum, device, dtype, with_extremal=True) | 1743 | self._test_sum_reduction_vs_numpy(torch.sum, np.sum, device, dtype, with_extremal=True) |
| 1685 | self._test_sum_reduction_vs_numpy(torch.sum, np.sum, device, dtype, with_keepdim=True) | 1744 | self._test_sum_reduction_vs_numpy(torch.sum, np.sum, device, dtype, with_keepdim=True) |
| 1686 | 1745 | ||
| 1687 | 1746 | ||
| 1688 | - @dtypes(*all_types_and(torch.half)) | 1747 | + @dtypes(*set(all_types_and(torch.half)) - {torch.uint8}) |
| 1689 | def test_nansum_vs_numpy(self, device, dtype): | 1748 | def test_nansum_vs_numpy(self, device, dtype): |
| 1690 | self._test_sum_reduction_vs_numpy(torch.nansum, np.nansum, device, dtype) | 1749 | self._test_sum_reduction_vs_numpy(torch.nansum, np.nansum, device, dtype) |
| 1691 | self._test_sum_reduction_vs_numpy(torch.nansum, np.nansum, device, dtype, with_extremal=True) | 1750 | self._test_sum_reduction_vs_numpy(torch.nansum, np.nansum, device, dtype, with_extremal=True) |
| @@ -1703,12 +1762,14 @@ class TestReductions(TestCase): | |||
| 1703 | out_dtype = dtype | 1762 | out_dtype = dtype |
| 1704 | inp_dtypes = all_types_and(torch.half) if out_dtype.is_floating_point else integral_types() | 1763 | inp_dtypes = all_types_and(torch.half) if out_dtype.is_floating_point else integral_types() |
| 1705 | for inp_dtype in inp_dtypes: | 1764 | for inp_dtype in inp_dtypes: |
| 1765 | + # Investigate why the output is not close to numpy. | ||
| 1766 | + atol, rtol = self._get_relaxed_tolerances_for(dtype) | ||
| 1706 | shape = _rand_shape(random.randint(2, 5), min_size=5, max_size=10) | 1767 | shape = _rand_shape(random.randint(2, 5), min_size=5, max_size=10) |
| 1707 | x = _generate_input(shape, inp_dtype, device, with_extremal=False) | 1768 | x = _generate_input(shape, inp_dtype, device, with_extremal=False) |
| 1708 | torch_fn = partial(torch.nansum, dtype=out_dtype) | 1769 | torch_fn = partial(torch.nansum, dtype=out_dtype) |
| 1709 | np_out_dtype = torch_to_numpy_dtype_dict[out_dtype] | 1770 | np_out_dtype = torch_to_numpy_dtype_dict[out_dtype] |
| 1710 | np_fn = partial(np.nansum, dtype=np_out_dtype) | 1771 | np_fn = partial(np.nansum, dtype=np_out_dtype) |
| 1711 | - self.compare_with_numpy(torch_fn, np_fn, x, device=None, dtype=None) | 1772 | + self.compare_with_numpy(torch_fn, np_fn, x, device=None, dtype=None, atol=atol, rtol=rtol) |
| 1712 | 1773 | ||
| 1713 | 1774 | ||
| 1714 | def test_argminmax_multiple(self, device, dtype): | 1775 | def test_argminmax_multiple(self, device, dtype): |
| @@ -3500,6 +3561,10 @@ as the input tensor excluding its innermost dimension'): | |||
| 3500 | 3561 | ||
| 3501 | expected = np.asarray(expected) # transform numpy scalars to numpy.ndarray instances | 3562 | expected = np.asarray(expected) # transform numpy scalars to numpy.ndarray instances |
| 3502 | 3563 | ||
| 3564 | + # Numpy differs, producing uint32 on Windows | ||
| 3565 | + if expected.dtype in [np.uint64, np.uint32]: | ||
| 3566 | + exact_dtype = False | ||
| 3567 | + | ||
| 3503 | msg = ("Failed to produce expected results! Input tensor was" | 3568 | msg = ("Failed to produce expected results! Input tensor was" |
| 3504 | f" {t}, torch result is {actual}, and reference result is" | 3569 | f" {t}, torch result is {actual}, and reference result is" |
| 3505 | f" {expected}.") if t.numel() < 10 else None | 3570 | f" {expected}.") if t.numel() < 10 else None |