已合并
Update test_reductions of pt2.4 #12189
AtomGit-Bot创建于 2024年6月4日
Update test_reductions of pt2.4 #12189
已合并
AtomGit-Bot创建于 2024年6月4日
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 @dtypesIfPRIVATEUSE1(torch.half, torch.bfloat16, torch.float, torch.double)1125 @dtypesIfPRIVATEUSE1(torch.half, torch.bfloat16, torch.float, torch.double)
1119 @dtypes(torch.half, torch.bfloat16, torch.float, torch.double)1126 @dtypes(torch.half, torch.bfloat16, torch.float, torch.double)
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+ @onlyCPU
1346+ @dtypes(torch.bfloat16, torch.float16)
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 @onlyCPU1391 @onlyCPU
1339 @dtypes(torch.bool, torch.double)1392 @dtypes(torch.bool, torch.double)
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 tensor1410 # 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 integers1723 # 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 checking1724 # 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 True1726+ 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+ @dtypes(*set(all_types_and(torch.half)) - {torch.uint8})
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 = dtype1762 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 @dtypes(*all_types_and(torch.half))1774 @dtypes(*all_types_and(torch.half))
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 instances3562 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 None3570 f" {expected}.") if t.numel() < 10 else None