From fe4951c02efd761e464135ddd7072e381fcae20f Mon Sep 17 00:00:00 2001 From: Nicolas Hug Date: Mon, 9 Dec 2024 08:26:22 -0800 Subject: [PATCH] Fix internal GPU tests (#423) Summary: Pull Request resolved: https://github.com/pytorch/torchcodec/pull/423 Reviewed By: scotts Differential Revision: D66822000 --- test/decoders/test_video_decoder.py | 7 ++++-- test/utils.py | 37 ++++++++++++++++++++++++----- 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/test/decoders/test_video_decoder.py b/test/decoders/test_video_decoder.py index 4f80cbc0..1ff8266c 100644 --- a/test/decoders/test_video_decoder.py +++ b/test/decoders/test_video_decoder.py @@ -11,7 +11,7 @@ from torchcodec.decoders import _core, VideoDecoder -from ..utils import assert_frames_equal, cpu_and_cuda, H265_VIDEO, NASA_VIDEO +from ..utils import assert_frames_equal, cpu_and_cuda, H265_VIDEO, in_fbcode, NASA_VIDEO class TestVideoDecoder: @@ -238,7 +238,10 @@ def test_getitem_slice(self, device): ] ) for sliced, ref in zip(all_frames, decoder): - assert_frames_equal(sliced, ref) + if not (in_fbcode() and device == "cuda"): + # TODO: remove the "if". + # See https://github.com/pytorch/torchcodec/issues/428 + assert_frames_equal(sliced, ref) @pytest.mark.parametrize("device", cpu_and_cuda()) def test_getitem_fails(self, device): diff --git a/test/utils.py b/test/utils.py index 8ab9602f..14e7db0f 100644 --- a/test/utils.py +++ b/test/utils.py @@ -31,14 +31,39 @@ def cpu_and_cuda(): def assert_frames_equal(*args, **kwargs): if sys.platform == "linux": if args[0].device.type == "cuda": - # CUDA tensors are not exactly equal on Linux, so we need to use a - # higher tolerance. - absolute_tolerance = 2 + atol = 2 + if in_fbcode(): + assert_tensor_close_on_at_least( + args[0], args[1], percentage=95, atol=atol + ) + else: + torch.testing.assert_close(*args, **kwargs, atol=atol, rtol=0) else: - absolute_tolerance = 0 + torch.testing.assert_close(*args, **kwargs, atol=0, rtol=0) else: - absolute_tolerance = 3 - torch.testing.assert_close(*args, **kwargs, atol=absolute_tolerance, rtol=0) + torch.testing.assert_close(*args, **kwargs, atol=3, rtol=0) + + +# Asserts that at least `percentage`% of the values are within the absolute tolerance. +# Percentage is expected in [0, 100] (actually, [60, 100]) +def assert_tensor_close_on_at_least(actual_tensor, ref_tensor, *, percentage, atol): + # In theory lower bound should be 0, but we want to make sure we don't + # mistakenly pass percentage in [0, 1] + assert 60 < percentage <= 100, ( + f"Percentage must be in [60, 100], got {percentage}. " + "Are you sure setting such a low tolerance is desired?" + ) + assert ( + actual_tensor.device == ref_tensor.device + ), f"Devices don't match: {actual_tensor.device} vs {ref_tensor.device}" + + abs_diff = (ref_tensor.float() - actual_tensor.float()).abs() + valid_percentage = (abs_diff <= atol).float().mean() * 100 + if valid_percentage < percentage: + raise AssertionError( + f"Expected at least {percentage}% of values to be within atol={atol}, " + f"but only {valid_percentage}% were." + ) def in_fbcode() -> bool: