From f02bd4f8bf7ee3bce9ca6200dd9998a8f5ac571a Mon Sep 17 00:00:00 2001 From: Andrey Talman Date: Fri, 20 Dec 2024 18:44:04 +0000 Subject: [PATCH 1/3] Revert "Temporarily disable linux CPU tests (#416)". And put back cuda 11.8, cuda 12.4 tests (#441) --- .github/workflows/linux_cuda_wheel.yaml | 2 +- .github/workflows/linux_wheel.yaml | 137 ++++++++++++------------ 2 files changed, 69 insertions(+), 70 deletions(-) diff --git a/.github/workflows/linux_cuda_wheel.yaml b/.github/workflows/linux_cuda_wheel.yaml index a4b001c2..27d7a7a4 100644 --- a/.github/workflows/linux_cuda_wheel.yaml +++ b/.github/workflows/linux_cuda_wheel.yaml @@ -66,7 +66,7 @@ jobs: # For the actual release we should add that label and change this to # include more python versions. python-version: ['3.9'] - cuda-version: ['12.6'] + cuda-version: ['11.8', '12.4', '12.6'] ffmpeg-version-for-tests: ['5', '6', '7'] container: image: "pytorch/manylinux2_28-builder:cuda${{ matrix.cuda-version }}" diff --git a/.github/workflows/linux_wheel.yaml b/.github/workflows/linux_wheel.yaml index be5c1b0c..38f25733 100644 --- a/.github/workflows/linux_wheel.yaml +++ b/.github/workflows/linux_wheel.yaml @@ -24,6 +24,7 @@ defaults: shell: bash -l -eo pipefail {0} jobs: + generate-matrix: uses: pytorch/test-infra/.github/workflows/generate_binary_build_matrix.yml@main with: @@ -55,76 +56,74 @@ jobs: build-platform: "python-build-package" build-command: "BUILD_AGAINST_ALL_FFMPEG_FROM_S3=1 python -m build --wheel -vvv --no-isolation" -# TODO: Put this back!!!! -# See https://github.com/pytorch/torchcodec/issues/415 -# install-and-test: -# runs-on: ubuntu-latest -# strategy: -# fail-fast: false -# matrix: -# python-version: ['3.9'] -# ffmpeg-version-for-tests: ['4.4.2', '5.1.2', '6.1.1', '7.0.1'] -# needs: build -# steps: -# - uses: actions/download-artifact@v3 -# with: -# name: pytorch_torchcodec__${{ matrix.python-version }}_cpu_x86_64 -# path: pytorch/torchcodec/dist/ -# - name: Setup conda env -# uses: conda-incubator/setup-miniconda@v2 -# with: -# auto-update-conda: true -# miniconda-version: "latest" -# activate-environment: test -# python-version: ${{ matrix.python-version }} -# - name: Update pip -# run: python -m pip install --upgrade pip -# - name: Install PyTorch -# run: | -# python -m pip install --pre torch --index-url https://download.pytorch.org/whl/nightly/cpu -# - name: Install torchcodec from the wheel -# run: | -# wheel_path=`find pytorch/torchcodec/dist -type f -name "*.whl"` -# echo Installing $wheel_path -# python -m pip install $wheel_path -vvv + install-and-test: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + python-version: ['3.9'] + ffmpeg-version-for-tests: ['4.4.2', '5.1.2', '6.1.1', '7.0.1'] + needs: build + steps: + - uses: actions/download-artifact@v3 + with: + name: pytorch_torchcodec__${{ matrix.python-version }}_cpu_x86_64 + path: pytorch/torchcodec/dist/ + - name: Setup conda env + uses: conda-incubator/setup-miniconda@v2 + with: + auto-update-conda: true + miniconda-version: "latest" + activate-environment: test + python-version: ${{ matrix.python-version }} + - name: Update pip + run: python -m pip install --upgrade pip + - name: Install PyTorch + run: | + python -m pip install --pre torch --index-url https://download.pytorch.org/whl/nightly/cpu + - name: Install torchcodec from the wheel + run: | + wheel_path=`find pytorch/torchcodec/dist -type f -name "*.whl"` + echo Installing $wheel_path + python -m pip install $wheel_path -vvv -# - name: Check out repo -# uses: actions/checkout@v3 -# - name: Install ffmpeg, post build -# run: | -# # Ideally we would have checked for that before installing the wheel, -# # but we need to checkout the repo to access this file, and we don't -# # want to checkout the repo before installing the wheel to avoid any -# # side-effect. It's OK. -# source packaging/helpers.sh -# assert_ffmpeg_not_installed + - name: Check out repo + uses: actions/checkout@v3 + - name: Install ffmpeg, post build + run: | + # Ideally we would have checked for that before installing the wheel, + # but we need to checkout the repo to access this file, and we don't + # want to checkout the repo before installing the wheel to avoid any + # side-effect. It's OK. + source packaging/helpers.sh + assert_ffmpeg_not_installed -# conda install "ffmpeg=${{ matrix.ffmpeg-version-for-tests }}" -c conda-forge -# ffmpeg -version + conda install "ffmpeg=${{ matrix.ffmpeg-version-for-tests }}" -c conda-forge + ffmpeg -version -# - name: Install test dependencies -# run: | -# python -m pip install --pre torchvision --index-url https://download.pytorch.org/whl/nightly/cpu -# # Ideally we would find a way to get those dependencies from pyproject.toml -# python -m pip install numpy pytest pillow + - name: Install test dependencies + run: | + python -m pip install --pre torchvision --index-url https://download.pytorch.org/whl/nightly/cpu + # Ideally we would find a way to get those dependencies from pyproject.toml + python -m pip install numpy pytest pillow -# - name: Delete the src/ folder just for fun -# run: | -# # The only reason we checked-out the repo is to get access to the -# # tests. We don't care about the rest. Out of precaution, we delete -# # the src/ folder to be extra sure that we're running the code from -# # the installed wheel rather than from the source. -# # This is just to be extra cautious and very overkill because a) -# # there's no way the `torchcodec` package from src/ can be found from -# # the PythonPath: the main point of `src/` is precisely to protect -# # against that and b) if we ever were to execute code from -# # `src/torchcodec`, it would fail loudly because the built .so files -# # aren't present there. -# rm -r src/ -# ls -# - name: Smoke test -# run: | -# python -X faulthandler test/decoders/manual_smoke_test.py -# - name: Run Python tests -# run: | -# pytest test -vvv + - name: Delete the src/ folder just for fun + run: | + # The only reason we checked-out the repo is to get access to the + # tests. We don't care about the rest. Out of precaution, we delete + # the src/ folder to be extra sure that we're running the code from + # the installed wheel rather than from the source. + # This is just to be extra cautious and very overkill because a) + # there's no way the `torchcodec` package from src/ can be found from + # the PythonPath: the main point of `src/` is precisely to protect + # against that and b) if we ever were to execute code from + # `src/torchcodec`, it would fail loudly because the built .so files + # aren't present there. + rm -r src/ + ls + - name: Smoke test + run: | + python -X faulthandler test/decoders/manual_smoke_test.py + - name: Run Python tests + run: | + pytest test -vvv From cd7cef6fd8c8c556035d536404802032b1a92b6c Mon Sep 17 00:00:00 2001 From: Nicolas Hug Date: Thu, 9 Jan 2025 14:31:18 +0000 Subject: [PATCH 2/3] Rename `prevFrame` into `prevFrameContext` (#447) --- src/torchcodec/decoders/_core/VideoDecoder.cpp | 9 +++++---- src/torchcodec/decoders/_core/VideoDecoder.h | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/torchcodec/decoders/_core/VideoDecoder.cpp b/src/torchcodec/decoders/_core/VideoDecoder.cpp index 5fa7a872..7492ff35 100644 --- a/src/torchcodec/decoders/_core/VideoDecoder.cpp +++ b/src/torchcodec/decoders/_core/VideoDecoder.cpp @@ -939,9 +939,10 @@ void VideoDecoder::convertAVFrameToDecodedOutputOnCPU( outputTensor = preAllocatedOutputTensor.value_or(allocateEmptyHWCTensor( expectedOutputHeight, expectedOutputWidth, torch::kCPU)); - if (!streamInfo.swsContext || streamInfo.prevFrame != frameContext) { + if (!streamInfo.swsContext || + streamInfo.prevFrameContext != frameContext) { createSwsContext(streamInfo, frameContext, frame->colorspace); - streamInfo.prevFrame = frameContext; + streamInfo.prevFrameContext = frameContext; } int resultHeight = convertFrameToTensorUsingSwsScale(streamIndex, frame, outputTensor); @@ -960,10 +961,10 @@ void VideoDecoder::convertAVFrameToDecodedOutputOnCPU( streamInfo.colorConversionLibrary == ColorConversionLibrary::FILTERGRAPH) { if (!streamInfo.filterState.filterGraph || - streamInfo.prevFrame != frameContext) { + streamInfo.prevFrameContext != frameContext) { createFilterGraph( streamInfo, expectedOutputHeight, expectedOutputWidth); - streamInfo.prevFrame = frameContext; + streamInfo.prevFrameContext = frameContext; } outputTensor = convertFrameToTensorUsingFilterGraph(streamIndex, frame); diff --git a/src/torchcodec/decoders/_core/VideoDecoder.h b/src/torchcodec/decoders/_core/VideoDecoder.h index 0893d9a6..56d83fbf 100644 --- a/src/torchcodec/decoders/_core/VideoDecoder.h +++ b/src/torchcodec/decoders/_core/VideoDecoder.h @@ -342,7 +342,7 @@ class VideoDecoder { ColorConversionLibrary colorConversionLibrary = FILTERGRAPH; std::vector keyFrames; std::vector allFrames; - DecodedFrameContext prevFrame; + DecodedFrameContext prevFrameContext; UniqueSwsContext swsContext; }; // Returns the key frame index of the presentation timestamp using FFMPEG's From 598495a97256e8dec01de3e2da2e9596aab55ce2 Mon Sep 17 00:00:00 2001 From: Scott Schneider Date: Thu, 9 Jan 2025 11:31:59 -0500 Subject: [PATCH 3/3] Restore comment about getting stream info (#449) --- src/torchcodec/decoders/_core/VideoDecoder.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/torchcodec/decoders/_core/VideoDecoder.cpp b/src/torchcodec/decoders/_core/VideoDecoder.cpp index 7492ff35..2c955551 100644 --- a/src/torchcodec/decoders/_core/VideoDecoder.cpp +++ b/src/torchcodec/decoders/_core/VideoDecoder.cpp @@ -237,6 +237,11 @@ VideoDecoder::VideoDecoder(const void* buffer, size_t length) { void VideoDecoder::initializeDecoder() { TORCH_CHECK(!initialized_, "Attempted double initialization."); + // In principle, the AVFormatContext should be filled in by the call to + // avformat_open_input() which reads the header. However, some formats do not + // store enough info in the header, so we call avformat_find_stream_info() + // which decodes a few frames to get missing info. For more, see: + // https://ffmpeg.org/doxygen/7.0/group__lavf__decoding.html int ffmpegStatus = avformat_find_stream_info(formatContext_.get(), nullptr); if (ffmpegStatus < 0) { throw std::runtime_error(