diff --git a/test/conftest.py b/test/conftest.py index f5db4b5d6..bef5291e5 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -23,7 +23,7 @@ def pytest_collection_modifyitems(items): # with the @needs_cuda decorator. It will also exist if it was # parametrized with a parameter that has the mark: for example if a test # is parametrized with - # @pytest.mark.parametrize('device', cpu_and_cuda()) + # @pytest.mark.parametrize('device', all_supported_devices()) # the "instances" of the tests where device == 'cuda' will have the # 'needs_cuda' mark, and the ones with device == 'cpu' won't have the # mark. diff --git a/test/test_decoders.py b/test/test_decoders.py index d7f53dee3..6b54a1a52 100644 --- a/test/test_decoders.py +++ b/test/test_decoders.py @@ -22,9 +22,9 @@ ) from .utils import ( + all_supported_devices, assert_frames_equal, AV1_VIDEO, - cpu_and_cuda, get_ffmpeg_major_version, H264_10BITS, H265_10BITS, @@ -163,7 +163,7 @@ def test_create_fails(self): VideoDecoder(NASA_VIDEO.path, seek_mode="blah") @pytest.mark.parametrize("num_ffmpeg_threads", (1, 4)) - @pytest.mark.parametrize("device", cpu_and_cuda()) + @pytest.mark.parametrize("device", all_supported_devices()) @pytest.mark.parametrize("seek_mode", ("exact", "approximate")) def test_getitem_int(self, num_ffmpeg_threads, device, seek_mode): decoder = VideoDecoder( @@ -213,7 +213,7 @@ def test_getitem_numpy_int(self): assert_frames_equal(ref_frame1, decoder[numpy.uint32(1)]) assert_frames_equal(ref_frame180, decoder[numpy.uint32(180)]) - @pytest.mark.parametrize("device", cpu_and_cuda()) + @pytest.mark.parametrize("device", all_supported_devices()) @pytest.mark.parametrize("seek_mode", ("exact", "approximate")) def test_getitem_slice(self, device, seek_mode): decoder = VideoDecoder(NASA_VIDEO.path, device=device, seek_mode=seek_mode) @@ -373,7 +373,7 @@ def test_device_instance(self): decoder = VideoDecoder(NASA_VIDEO.path, device=torch.device("cpu")) assert isinstance(decoder.metadata, VideoStreamMetadata) - @pytest.mark.parametrize("device", cpu_and_cuda()) + @pytest.mark.parametrize("device", all_supported_devices()) @pytest.mark.parametrize("seek_mode", ("exact", "approximate")) def test_getitem_fails(self, device, seek_mode): decoder = VideoDecoder(NASA_VIDEO.path, device=device, seek_mode=seek_mode) @@ -390,7 +390,7 @@ def test_getitem_fails(self, device, seek_mode): with pytest.raises(TypeError, match="Unsupported key type"): frame = decoder[2.3] # noqa - @pytest.mark.parametrize("device", cpu_and_cuda()) + @pytest.mark.parametrize("device", all_supported_devices()) @pytest.mark.parametrize("seek_mode", ("exact", "approximate")) def test_iteration(self, device, seek_mode): decoder = VideoDecoder(NASA_VIDEO.path, device=device, seek_mode=seek_mode) @@ -437,7 +437,7 @@ def test_iteration_slow(self): assert iterations == len(decoder) == 390 - @pytest.mark.parametrize("device", cpu_and_cuda()) + @pytest.mark.parametrize("device", all_supported_devices()) @pytest.mark.parametrize("seek_mode", ("exact", "approximate")) def test_get_frame_at(self, device, seek_mode): decoder = VideoDecoder(NASA_VIDEO.path, device=device, seek_mode=seek_mode) @@ -475,7 +475,7 @@ def test_get_frame_at(self, device, seek_mode): frame9 = decoder.get_frame_at(numpy.uint32(9)) assert_frames_equal(ref_frame9, frame9.data) - @pytest.mark.parametrize("device", cpu_and_cuda()) + @pytest.mark.parametrize("device", all_supported_devices()) def test_get_frame_at_tuple_unpacking(self, device): decoder = VideoDecoder(NASA_VIDEO.path, device=device) @@ -486,7 +486,7 @@ def test_get_frame_at_tuple_unpacking(self, device): assert frame.pts_seconds == pts assert frame.duration_seconds == duration - @pytest.mark.parametrize("device", cpu_and_cuda()) + @pytest.mark.parametrize("device", all_supported_devices()) @pytest.mark.parametrize("seek_mode", ("exact", "approximate")) def test_get_frame_at_fails(self, device, seek_mode): decoder = VideoDecoder(NASA_VIDEO.path, device=device, seek_mode=seek_mode) @@ -500,7 +500,7 @@ def test_get_frame_at_fails(self, device, seek_mode): with pytest.raises(IndexError, match="must be less than"): frame = decoder.get_frame_at(10000) # noqa - @pytest.mark.parametrize("device", cpu_and_cuda()) + @pytest.mark.parametrize("device", all_supported_devices()) @pytest.mark.parametrize("seek_mode", ("exact", "approximate")) def test_get_frames_at(self, device, seek_mode): decoder = VideoDecoder(NASA_VIDEO.path, device=device, seek_mode=seek_mode) @@ -551,7 +551,7 @@ def test_get_frames_at(self, device, seek_mode): frames.duration_seconds, expected_duration_seconds, atol=1e-4, rtol=0 ) - @pytest.mark.parametrize("device", cpu_and_cuda()) + @pytest.mark.parametrize("device", all_supported_devices()) @pytest.mark.parametrize("seek_mode", ("exact", "approximate")) def test_get_frames_at_fails(self, device, seek_mode): decoder = VideoDecoder(NASA_VIDEO.path, device=device, seek_mode=seek_mode) @@ -568,7 +568,7 @@ def test_get_frames_at_fails(self, device, seek_mode): with pytest.raises(RuntimeError, match="Expected a value of type"): decoder.get_frames_at([0.3]) - @pytest.mark.parametrize("device", cpu_and_cuda()) + @pytest.mark.parametrize("device", all_supported_devices()) def test_get_frame_at_av1(self, device): if device == "cuda" and get_ffmpeg_major_version() == 4: return @@ -581,7 +581,7 @@ def test_get_frame_at_av1(self, device): assert decoded_frame10.pts_seconds == ref_frame_info10.pts_seconds assert_frames_equal(decoded_frame10.data, ref_frame10.to(device=device)) - @pytest.mark.parametrize("device", cpu_and_cuda()) + @pytest.mark.parametrize("device", all_supported_devices()) @pytest.mark.parametrize("seek_mode", ("exact", "approximate")) def test_get_frame_played_at(self, device, seek_mode): decoder = VideoDecoder(NASA_VIDEO.path, device=device, seek_mode=seek_mode) @@ -610,7 +610,7 @@ def test_get_frame_played_at_h265(self): ref_frame6 = H265_VIDEO.get_frame_data_by_index(5) assert_frames_equal(ref_frame6, decoder.get_frame_played_at(0.5).data) - @pytest.mark.parametrize("device", cpu_and_cuda()) + @pytest.mark.parametrize("device", all_supported_devices()) @pytest.mark.parametrize("seek_mode", ("exact", "approximate")) def test_get_frame_played_at_fails(self, device, seek_mode): decoder = VideoDecoder(NASA_VIDEO.path, device=device, seek_mode=seek_mode) @@ -621,7 +621,7 @@ def test_get_frame_played_at_fails(self, device, seek_mode): with pytest.raises(IndexError, match="Invalid pts in seconds"): frame = decoder.get_frame_played_at(100.0) # noqa - @pytest.mark.parametrize("device", cpu_and_cuda()) + @pytest.mark.parametrize("device", all_supported_devices()) @pytest.mark.parametrize("seek_mode", ("exact", "approximate")) def test_get_frames_played_at(self, device, seek_mode): @@ -660,7 +660,7 @@ def test_get_frames_played_at(self, device, seek_mode): frames.duration_seconds, expected_duration_seconds, atol=1e-4, rtol=0 ) - @pytest.mark.parametrize("device", cpu_and_cuda()) + @pytest.mark.parametrize("device", all_supported_devices()) @pytest.mark.parametrize("seek_mode", ("exact", "approximate")) def test_get_frames_played_at_fails(self, device, seek_mode): decoder = VideoDecoder(NASA_VIDEO.path, device=device, seek_mode=seek_mode) @@ -674,7 +674,7 @@ def test_get_frames_played_at_fails(self, device, seek_mode): with pytest.raises(RuntimeError, match="Expected a value of type"): decoder.get_frames_played_at(["bad"]) - @pytest.mark.parametrize("device", cpu_and_cuda()) + @pytest.mark.parametrize("device", all_supported_devices()) @pytest.mark.parametrize("stream_index", [0, 3, None]) @pytest.mark.parametrize("seek_mode", ("exact", "approximate")) def test_get_frames_in_range(self, stream_index, device, seek_mode): @@ -779,7 +779,7 @@ def test_get_frames_in_range(self, stream_index, device, seek_mode): empty_frames.duration_seconds, NASA_VIDEO.empty_duration_seconds ) - @pytest.mark.parametrize("device", cpu_and_cuda()) + @pytest.mark.parametrize("device", all_supported_devices()) @pytest.mark.parametrize("seek_mode", ("exact", "approximate")) def test_get_frames_in_range_slice_indices_syntax(self, device, seek_mode): decoder = VideoDecoder( @@ -831,7 +831,7 @@ def test_get_frames_in_range_slice_indices_syntax(self, device, seek_mode): ).to(device) assert_frames_equal(frames387_None.data, reference_frame387_389) - @pytest.mark.parametrize("device", cpu_and_cuda()) + @pytest.mark.parametrize("device", all_supported_devices()) @pytest.mark.parametrize("seek_mode", ("exact", "approximate")) @patch("torchcodec._core._metadata._get_stream_json_metadata") def test_get_frames_with_missing_num_frames_metadata( @@ -894,7 +894,7 @@ def test_get_frames_with_missing_num_frames_metadata( lambda decoder: decoder.get_frames_played_in_range(0, 1).data, ), ) - @pytest.mark.parametrize("device", cpu_and_cuda()) + @pytest.mark.parametrize("device", all_supported_devices()) @pytest.mark.parametrize("seek_mode", ("exact", "approximate")) def test_dimension_order(self, dimension_order, frame_getter, device, seek_mode): decoder = VideoDecoder( @@ -922,7 +922,7 @@ def test_dimension_order_fails(self): VideoDecoder(NASA_VIDEO.path, dimension_order="NCDHW") @pytest.mark.parametrize("stream_index", [0, 3, None]) - @pytest.mark.parametrize("device", cpu_and_cuda()) + @pytest.mark.parametrize("device", all_supported_devices()) @pytest.mark.parametrize("seek_mode", ("exact", "approximate")) def test_get_frames_by_pts_in_range(self, stream_index, device, seek_mode): decoder = VideoDecoder( @@ -1061,7 +1061,7 @@ def test_get_frames_by_pts_in_range(self, stream_index, device, seek_mode): ) assert_frames_equal(all_frames.data, decoder[:]) - @pytest.mark.parametrize("device", cpu_and_cuda()) + @pytest.mark.parametrize("device", all_supported_devices()) @pytest.mark.parametrize("seek_mode", ("exact", "approximate")) def test_get_frames_by_pts_in_range_fails(self, device, seek_mode): decoder = VideoDecoder(NASA_VIDEO.path, device=device, seek_mode=seek_mode) @@ -1075,7 +1075,7 @@ def test_get_frames_by_pts_in_range_fails(self, device, seek_mode): with pytest.raises(ValueError, match="Invalid stop seconds"): frame = decoder.get_frames_played_in_range(0, 23) # noqa - @pytest.mark.parametrize("device", cpu_and_cuda()) + @pytest.mark.parametrize("device", all_supported_devices()) def test_get_key_frame_indices(self, device): decoder = VideoDecoder(NASA_VIDEO.path, device=device, seek_mode="exact") key_frame_indices = decoder._get_key_frame_indices() @@ -1120,7 +1120,7 @@ def test_get_key_frame_indices(self, device): # TODO investigate why this fails internally. @pytest.mark.skipif(in_fbcode(), reason="Compile test fails internally.") - @pytest.mark.parametrize("device", cpu_and_cuda()) + @pytest.mark.parametrize("device", all_supported_devices()) def test_compile(self, device): decoder = VideoDecoder(NASA_VIDEO.path, device=device) diff --git a/test/test_ops.py b/test/test_ops.py index d86cb2437..d2f2fd3b1 100644 --- a/test/test_ops.py +++ b/test/test_ops.py @@ -42,8 +42,8 @@ ) from .utils import ( + all_supported_devices, assert_frames_equal, - cpu_and_cuda, get_ffmpeg_major_version, NASA_AUDIO, NASA_AUDIO_MP3, @@ -60,7 +60,7 @@ class TestVideoDecoderOps: - @pytest.mark.parametrize("device", cpu_and_cuda()) + @pytest.mark.parametrize("device", all_supported_devices()) def test_seek_and_next(self, device): decoder = create_from_file(str(NASA_VIDEO.path)) add_video_stream(decoder, device=device) @@ -77,7 +77,7 @@ def test_seek_and_next(self, device): ) assert_frames_equal(frame_time6, reference_frame_time6.to(device)) - @pytest.mark.parametrize("device", cpu_and_cuda()) + @pytest.mark.parametrize("device", all_supported_devices()) def test_seek_to_negative_pts(self, device): decoder = create_from_file(str(NASA_VIDEO.path)) add_video_stream(decoder, device=device) @@ -89,7 +89,7 @@ def test_seek_to_negative_pts(self, device): frame0, _, _ = get_next_frame(decoder) assert_frames_equal(frame0, reference_frame0.to(device)) - @pytest.mark.parametrize("device", cpu_and_cuda()) + @pytest.mark.parametrize("device", all_supported_devices()) def test_get_frame_at_pts(self, device): decoder = create_from_file(str(NASA_VIDEO.path)) add_video_stream(decoder, device=device) @@ -113,7 +113,7 @@ def test_get_frame_at_pts(self, device): with pytest.raises(AssertionError): assert_frames_equal(next_frame, reference_frame6.to(device)) - @pytest.mark.parametrize("device", cpu_and_cuda()) + @pytest.mark.parametrize("device", all_supported_devices()) def test_get_frame_at_index(self, device): decoder = create_from_file(str(NASA_VIDEO.path)) add_video_stream(decoder, device=device) @@ -131,7 +131,7 @@ def test_get_frame_at_index(self, device): reference_frame389 = NASA_VIDEO.get_frame_data_by_index(389) assert_frames_equal(frame389[0], reference_frame389.to(device)) - @pytest.mark.parametrize("device", cpu_and_cuda()) + @pytest.mark.parametrize("device", all_supported_devices()) def test_get_frame_with_info_at_index(self, device): decoder = create_from_file(str(NASA_VIDEO.path)) add_video_stream(decoder, device=device) @@ -143,7 +143,7 @@ def test_get_frame_with_info_at_index(self, device): assert pts.item() == pytest.approx(6.006, rel=1e-3) assert duration.item() == pytest.approx(0.03337, rel=1e-3) - @pytest.mark.parametrize("device", cpu_and_cuda()) + @pytest.mark.parametrize("device", all_supported_devices()) def test_get_frames_at_indices(self, device): decoder = create_from_file(str(NASA_VIDEO.path)) add_video_stream(decoder, device=device) @@ -155,7 +155,7 @@ def test_get_frames_at_indices(self, device): assert_frames_equal(frames0and180[0], reference_frame0.to(device)) assert_frames_equal(frames0and180[1], reference_frame180.to(device)) - @pytest.mark.parametrize("device", cpu_and_cuda()) + @pytest.mark.parametrize("device", all_supported_devices()) def test_get_frames_at_indices_unsorted_indices(self, device): decoder = create_from_file(str(NASA_VIDEO.path)) _add_video_stream(decoder, device=device) @@ -182,7 +182,7 @@ def test_get_frames_at_indices_unsorted_indices(self, device): with pytest.raises(AssertionError): assert_frames_equal(frames[0], frames[-1]) - @pytest.mark.parametrize("device", cpu_and_cuda()) + @pytest.mark.parametrize("device", all_supported_devices()) def test_get_frames_at_indices_negative_indices(self, device): decoder = create_from_file(str(NASA_VIDEO.path)) add_video_stream(decoder, device=device) @@ -196,7 +196,7 @@ def test_get_frames_at_indices_negative_indices(self, device): assert_frames_equal(frames389and387and1[1], reference_frame387.to(device)) assert_frames_equal(frames389and387and1[2], reference_frame1.to(device)) - @pytest.mark.parametrize("device", cpu_and_cuda()) + @pytest.mark.parametrize("device", all_supported_devices()) def test_get_frames_at_indices_fail_on_invalid_negative_indices(self, device): decoder = create_from_file(str(NASA_VIDEO.path)) add_video_stream(decoder, device=device) @@ -208,7 +208,7 @@ def test_get_frames_at_indices_fail_on_invalid_negative_indices(self, device): decoder, frame_indices=[-10000, -3000] ) - @pytest.mark.parametrize("device", cpu_and_cuda()) + @pytest.mark.parametrize("device", all_supported_devices()) def test_get_frames_by_pts(self, device): decoder = create_from_file(str(NASA_VIDEO.path)) _add_video_stream(decoder, device=device) @@ -236,7 +236,7 @@ def test_get_frames_by_pts(self, device): with pytest.raises(AssertionError): assert_frames_equal(frames[0], frames[-1]) - @pytest.mark.parametrize("device", cpu_and_cuda()) + @pytest.mark.parametrize("device", all_supported_devices()) def test_pts_apis_against_index_ref(self, device): # Non-regression test for https://github.com/pytorch/torchcodec/pull/287 # Get all frames in the video, then query all frames with all time-based @@ -291,7 +291,7 @@ def test_pts_apis_against_index_ref(self, device): ) torch.testing.assert_close(pts_seconds, all_pts_seconds_ref, atol=0, rtol=0) - @pytest.mark.parametrize("device", cpu_and_cuda()) + @pytest.mark.parametrize("device", all_supported_devices()) def test_get_frames_in_range(self, device): decoder = create_from_file(str(NASA_VIDEO.path)) add_video_stream(decoder, device=device) @@ -331,7 +331,7 @@ def test_get_frames_in_range(self, device): empty_frame, *_ = get_frames_in_range(decoder, start=5, stop=5) assert_frames_equal(empty_frame, NASA_VIDEO.empty_chw_tensor.to(device)) - @pytest.mark.parametrize("device", cpu_and_cuda()) + @pytest.mark.parametrize("device", all_supported_devices()) def test_throws_exception_at_eof(self, device): decoder = create_from_file(str(NASA_VIDEO.path)) add_video_stream(decoder, device=device) @@ -346,7 +346,7 @@ def test_throws_exception_at_eof(self, device): with pytest.raises(IndexError, match="no more frames"): get_frame_at_pts(decoder, seconds=1000.0) - @pytest.mark.parametrize("device", cpu_and_cuda()) + @pytest.mark.parametrize("device", all_supported_devices()) def test_throws_exception_if_seek_too_far(self, device): decoder = create_from_file(str(NASA_VIDEO.path)) add_video_stream(decoder, device=device) @@ -355,7 +355,7 @@ def test_throws_exception_if_seek_too_far(self, device): with pytest.raises(IndexError, match="no more frames"): get_next_frame(decoder) - @pytest.mark.parametrize("device", cpu_and_cuda()) + @pytest.mark.parametrize("device", all_supported_devices()) def test_compile_seek_and_next(self, device): # TODO_OPEN_ISSUE Scott (T180277797): Get this to work with the inductor stack. Right now # compilation fails because it can't handle tensors of size unknown at @@ -379,7 +379,7 @@ def get_frame1_and_frame_time6(decoder): assert_frames_equal(frame0, reference_frame0.to(device)) assert_frames_equal(frame_time6, reference_frame_time6.to(device)) - @pytest.mark.parametrize("device", cpu_and_cuda()) + @pytest.mark.parametrize("device", all_supported_devices()) @pytest.mark.parametrize( "create_from", ("file", "tensor", "bytes", "file_like_rawio", "file_like_bufferedio"), @@ -509,7 +509,7 @@ def test_seek_mode_custom_frame_mappings_fails(self): get_ffmpeg_major_version() in (4, 5), reason="ffprobe isn't accurate on ffmpeg 4 and 5", ) - @pytest.mark.parametrize("device", cpu_and_cuda()) + @pytest.mark.parametrize("device", all_supported_devices()) def test_seek_mode_custom_frame_mappings(self, device): stream_index = 3 # custom_frame_index seek mode requires a stream index decoder = create_from_file( @@ -1015,7 +1015,7 @@ def get_all_frames(asset, sample_rate=None, stop_seconds=None): torch.testing.assert_close(frames_downsampled_to_8000, frames_8000_native) @pytest.mark.parametrize("buffering", (0, 1024)) - @pytest.mark.parametrize("device", cpu_and_cuda()) + @pytest.mark.parametrize("device", all_supported_devices()) def test_file_like_decoding(self, buffering, device): # Test to ensure that seeks and reads are actually going through the # methods on the IO object. diff --git a/test/utils.py b/test/utils.py index c258ac440..588fdd6df 100644 --- a/test/utils.py +++ b/test/utils.py @@ -23,7 +23,7 @@ def needs_cuda(test_item): return pytest.mark.needs_cuda(test_item) -def cpu_and_cuda(): +def all_supported_devices(): return ("cpu", pytest.param("cuda", marks=pytest.mark.needs_cuda))