Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 10 additions & 7 deletions .github/workflows/sanitizers.yml
Original file line number Diff line number Diff line change
Expand Up @@ -127,12 +127,13 @@ jobs:
# Exclude test_integer_motion_v2_coverage: triggers a SIGABRT under
# ASan due to an intentional huge-allocation pattern in the motion
# coverage path that the ASan allocator cannot satisfy.
# Exclude test_pic_preallocation: triggers a SIGABRT under ASan in
# addition to its pre-existing Linux exclusion; the test relies on
# allocation semantics that ASan's allocator intercepts fatally.
# test_pic_preallocation was removed from this list after PRs #765
# and #769 fixed the PREV_REF refcount leak and the dict leak in
# flush_context_threaded; all 8 sub-tests now pass under ASan+LSan,
# UBSan, and TSan (verified 2026-06-06).
TESTS=$(meson introspect build --tests 2>&1 \
| python3 -c "import json,sys; [print('libvmaf:'+t['name']) for t in json.load(sys.stdin)]" \
| grep -vE 'test_model$|test_y4m_alloc_failure$|test_gpu_picture_pool_uaf$|test_integer_motion_v2_coverage$|test_pic_preallocation$' || true)
| grep -vE 'test_model$|test_y4m_alloc_failure$|test_gpu_picture_pool_uaf$|test_integer_motion_v2_coverage$' || true)
echo "test count: $(echo "$TESTS" | wc -l)"
if [ -z "$TESTS" ]; then
echo "::error::Test enumeration produced empty list" >&2
Expand Down Expand Up @@ -203,11 +204,13 @@ jobs:
# T-GPU-POOL-UAF-OOM-TSAN-ABORT.
# Exclude test_integer_motion_v2_coverage: intentional huge-allocation
# pattern triggers SIGABRT under the TSan allocator.
# Exclude test_pic_preallocation: SIGABRT under TSan for the same
# intentional-huge-alloc reason as the ASan exclusion.
# test_pic_preallocation was removed from this list after PRs #765
# and #769 fixed the PREV_REF refcount leak and the dict leak in
# flush_context_threaded; all 8 sub-tests now pass under ASan+LSan,
# UBSan, and TSan (verified 2026-06-06).
TESTS=$(meson introspect build --tests 2>&1 \
| python3 -c "import json,sys; [print('libvmaf:'+t['name']) for t in json.load(sys.stdin)]" \
| grep -vE 'test_model$|test_y4m_alloc_failure$|test_gpu_picture_pool_uaf$|test_integer_motion_v2_coverage$|test_pic_preallocation$' || true)
| grep -vE 'test_model$|test_y4m_alloc_failure$|test_gpu_picture_pool_uaf$|test_integer_motion_v2_coverage$' || true)
echo "test count: $(echo "$TESTS" | wc -l)"
if [ -z "$TESTS" ]; then
echo "::error::Test enumeration produced empty list" >&2
Expand Down
31 changes: 19 additions & 12 deletions .github/workflows/tests-and-quality-gates.yml
Original file line number Diff line number Diff line change
Expand Up @@ -305,10 +305,11 @@ jobs:
# allocator aborts with SIGABRT instead of returning NULL.
# Exclude test_integer_motion_v2_coverage: intentional
# huge-allocation pattern triggers SIGABRT under ASan.
# Exclude test_pic_preallocation: SIGABRT under ASan from
# intentional huge-alloc; OOM path covered by unsanitized suite.
# (PR #767 added these to sanitizers.yml but missed this job.)
EXCLUDE='test_model$|test_y4m_alloc_failure$|test_gpu_picture_pool_uaf$|test_integer_motion_v2_coverage$|test_pic_preallocation$'
# test_pic_preallocation was removed from this list after PRs #765
# and #769 fixed the PREV_REF refcount leak and the dict leak in
# flush_context_threaded; all 8 sub-tests now pass under ASan+LSan
# (verified 2026-06-06).
EXCLUDE='test_model$|test_y4m_alloc_failure$|test_gpu_picture_pool_uaf$|test_integer_motion_v2_coverage$'
;;
undefined)
# UBSan deselects: test_model (NULL-to-nonnull memcpy
Expand All @@ -321,10 +322,13 @@ jobs:
# eliminating the SIGILL on non-AVX2 CI runners; confirmed
# clean under UBSan on current master.
# Exclude test_y4m_alloc_failure: RLIMIT_AS incompatible with UBSan runtime allocation.
# Exclude test_gpu_picture_pool_uaf, test_integer_motion_v2_coverage,
# test_pic_preallocation: same intentional huge-alloc / SIGABRT
# reason as ASan exclusions above. (PR #767 gap — see sanitizers.yml.)
EXCLUDE='test_model$|test_y4m_alloc_failure$|test_gpu_picture_pool_uaf$|test_integer_motion_v2_coverage$|test_pic_preallocation$'
# Exclude test_gpu_picture_pool_uaf, test_integer_motion_v2_coverage:
# same intentional huge-alloc / SIGABRT reason as ASan exclusions above.
# test_pic_preallocation was removed from this list after PRs #765 and
# #769 fixed the PREV_REF refcount leak and the dict leak in
# flush_context_threaded; all 8 sub-tests now pass under UBSan
# (verified 2026-06-06).
EXCLUDE='test_model$|test_y4m_alloc_failure$|test_gpu_picture_pool_uaf$|test_integer_motion_v2_coverage$'
;;
thread)
# TSan deselects: test_model (same defect as ASan/UBSan
Expand All @@ -334,10 +338,13 @@ jobs:
# mutex-domain mismatch; nightly TSan job was green on
# 2026-05-09 and 2026-05-10 (state.md entry).
# Exclude test_y4m_alloc_failure: RLIMIT_AS incompatible with TSan internal allocator.
# Exclude test_gpu_picture_pool_uaf, test_integer_motion_v2_coverage,
# test_pic_preallocation: intentional huge-alloc / SIGABRT under
# TSan allocator. (PR #767 gap — see sanitizers.yml and TSan job there.)
EXCLUDE='test_model$|test_y4m_alloc_failure$|test_gpu_picture_pool_uaf$|test_integer_motion_v2_coverage$|test_pic_preallocation$'
# Exclude test_gpu_picture_pool_uaf, test_integer_motion_v2_coverage:
# intentional huge-alloc / SIGABRT under TSan allocator.
# test_pic_preallocation was removed from this list after PRs #765 and
# #769 fixed the PREV_REF refcount leak and the dict leak in
# flush_context_threaded; all 8 sub-tests now pass under TSan
# (verified 2026-06-06).
EXCLUDE='test_model$|test_y4m_alloc_failure$|test_gpu_picture_pool_uaf$|test_integer_motion_v2_coverage$'
;;
*)
echo "::error::ADR-0347 deselect list is not defined for sanitizer=${{ matrix.sanitizer }}" >&2
Expand Down
2 changes: 1 addition & 1 deletion docs/state.md
Original file line number Diff line number Diff line change
Expand Up @@ -548,7 +548,7 @@ _Bugs closed in the last ~90 days. Older entries roll off into
| **T-SANITIZER-CLI-PARSE-CLEAN — `test_cli_parse` no longer needs sanitizer deselect** — the test was bundled into the broad T-SANITIZER-DEFECTS-REVEALED-758 exclusion after PR #758 made the sanitizer matrix enumerate the real C test set. Current master no longer reproduces the recorded `test_backend_cpu` non-zero sanitizer exit: the full `test_cli_parse` binary passes cleanly under ASan+LSan, UBSan, and TSan. | this PR (`fix/sanitizer-cli-parse-deselect-2026-05-15`) | — (stale sanitizer deselect cleanup; no ADR per CLAUDE §12 r8) | `ASAN_OPTIONS=detect_leaks=1:halt_on_error=1:abort_on_error=1:print_summary=1 ./build-asan-cli/test/test_cli_parse`, `UBSAN_OPTIONS=halt_on_error=1:abort_on_error=1:print_summary=1:print_stacktrace=1 ./build-ubsan-cli/test/test_cli_parse`, and `TSAN_OPTIONS=halt_on_error=1 ./build-tsan-cli/test/test_cli_parse` all pass. The workflow removes `test_cli_parse` from the ASan / UBSan / TSan `EXCLUDE` regexes; `test_predict` is retired by the companion cleanup. |
| **T-SANITIZER-PREDICT-CLEAN — `test_predict` no longer needs sanitizer deselect** — the test was bundled into the broad T-SANITIZER-DEFECTS-REVEALED-758 exclusion after PR #758 made the sanitizer matrix enumerate the real C test set. Current master no longer reproduces the recorded UBSan / TSan findings: the full `test_predict` binary passes cleanly under ASan+LSan, UBSan, and TSan. | this PR (`fix/sanitizer-predict-deselect-2026-05-15`) | — (stale sanitizer deselect cleanup; no ADR per CLAUDE §12 r8) | `ASAN_OPTIONS=detect_leaks=1:halt_on_error=1:abort_on_error=1:print_summary=1 ./build-asan-predict/test/test_predict`, `UBSAN_OPTIONS=halt_on_error=1:abort_on_error=1:print_summary=1:print_stacktrace=1 ./build-ubsan-predict/test/test_predict`, and `TSAN_OPTIONS=halt_on_error=1 ./build-tsan-predict/test/test_predict` all pass. The workflow removes `test_predict` from the ASan / UBSan / TSan `EXCLUDE` regexes; `test_cli_parse` was retired by the companion cleanup. |
| **T-VK-VIF-1.4-RESIDUAL-NVIDIA-DEFERRED — Vulkan VIF API-1.4 residual on NVIDIA RTX 4090 + driver 595.71.05** — Phase 3b left `integer_vif_scale2` failing 45/48 frames at max abs `1.527e-02` and 5-run non-deterministic int64 accumulator magnitudes after stronger fences failed. Phase 3c replaces the seven `subgroupAdd(int64_t)` accumulator reductions in `vif.comp` with an explicit `subgroupShuffleXor` butterfly helper, avoiding the NVIDIA int64 subgroup-add lowering path. | PR #787 (`fix/vulkan-vif-int64-subgroup-reduction`) | [ADR-0269](adr/0269-vif-ciede-precise-step-a.md) Phase-3c status update; [research-0108](research/0108-vulkan-vif-int64-subgroup-reduction-2026-05-14.md) | `glslc --target-env=vulkan1.3 -O core/src/feature/vulkan/shaders/vif.comp -o /tmp/vif.spv`; `ninja -C build-vulkan-int64 tools/vmaf`; cross-backend VIF gate at `places=4`: NVIDIA device 0 0/48 on all scales (scale2 max `2.000000e-06`, repeated 5 times), Arc device 1 0/48, RADV device 2 0/48. |
| **T-SANITIZER-PIC-PREALLOCATION-CLEAN — `test_pic_preallocation` no longer needs sanitizer deselect** — the test was bundled into the broad T-SANITIZER-DEFECTS-REVEALED-758 exclusion after PR #758 made the sanitizer matrix enumerate the real C test set. Current master no longer reproduces the original LSan / TSan signatures: the test passes cleanly under ASan+LSan, UBSan, and TSan. | this PR (`fix/sanitizer-pic-preallocation-2026-05-14`) | — (stale sanitizer deselect cleanup; no ADR per CLAUDE §12 r8) | `ASAN_OPTIONS=detect_leaks=1:halt_on_error=1 ./build-asan-score/test/test_pic_preallocation`, `UBSAN_OPTIONS=halt_on_error=1:print_stacktrace=1 ./build-ubsan-score/test/test_pic_preallocation`, and `TSAN_OPTIONS=halt_on_error=1 ./build-tsan-score/test/test_pic_preallocation` all pass. The workflow removes only `test_pic_preallocation` from the ASan / UBSan / TSan `EXCLUDE` regexes; `test_cli_parse` and `test_predict` remain tracked. |
| **T-SANITIZER-PIC-PREALLOCATION-CLEAN — `test_pic_preallocation` no longer needs sanitizer deselect** — the test was bundled into the broad T-SANITIZER-DEFECTS-REVEALED-758 exclusion after PR #758 made the sanitizer matrix enumerate the real C test set. PRs #765 (PREV_REF refcount leak in batch func) and #769 (dict leak via is_initialized guard in flush_context_threaded) together fixed all underlying bugs. All 8 sub-tests now pass cleanly under ASan+LSan, UBSan, and TSan. | DONE — PR this branch (`fix/dev-container-cuda-passthrough`, 2026-06-06). `test_pic_preallocation` removed from all 5 EXCLUDE regexes across `.github/workflows/sanitizers.yml` (2 lanes) and `.github/workflows/tests-and-quality-gates.yml` (3 lanes). | — (stale sanitizer deselect cleanup; no ADR per CLAUDE §12 r8) | 8/8 sub-tests pass: `ASAN_OPTIONS=detect_leaks=1:halt_on_error=1:abort_on_error=1 ./core/build-asan/test/test_pic_preallocation`, `UBSAN_OPTIONS=halt_on_error=1:print_stacktrace=1 ./core/build-pic/test/test_pic_preallocation`, `TSAN_OPTIONS=halt_on_error=1 ./core/build-tsan/test/test_pic_preallocation`. GCC debug build: 8/8. 20 consecutive GCC runs: all pass. |
| **SAN-FLOAT-MS-SSIM-MIN-DIM-LEAK** — `test_float_ms_ssim_min_dim::invoke_init` was excluded from the ASan deselect list based on a reported 240-byte / 6-allocation leak. Re-verification under `ASAN_OPTIONS=detect_leaks=1` (2026-05-13) shows zero leaks: `invoke_init` already calls `fex->close(fex)` + `free(priv)` on every code path (both early-reject and success). The exclusion was never needed after the teardown was added to the test body. | `ASAN_OPTIONS=detect_leaks=1 ./build-asan-test/test/test_float_ms_ssim_min_dim` → `3 tests run, 3 passed`, no leak report. | — | Removed `test_float_ms_ssim_min_dim$` from `EXCLUDE=` in `.github/workflows/tests-and-quality-gates.yml` (ASan lane). |
| **T-VMAFTUNE-RECOMMEND-FROM-CORPUS-FILTER — `vmaf-tune recommend --from-corpus` bypassed the library row filter** — The programmatic `recommend()` API dropped rows with `exit_status != 0`, missing / non-finite `vmaf_score`, and non-matching `encoder` / `preset`, but the CLI `--from-corpus` path called `pick_target_vmaf` / `pick_target_bitrate` directly. A failed encode row with high VMAF, a `NaN` score row, or a row for a different encoder could therefore win from the CLI even though the library API rejected it. | PR #781 (`fix/backlog-gap-pass-7-2026-05-14`) | — (bug fix; no ADR per CLAUDE §12 r8 — only-one-way fix) | `_run_recommend_from_corpus` now builds a `RecommendRequest` and delegates to `recommend()`. Regression tests cover failed-row filtering, `NaN` filtering, and encoder filtering. Smoke: `PYTHONPATH=tools/vmaf-tune/src .venv/bin/python -m pytest tools/vmaf-tune/tests/test_recommend.py -q` — 20/20 passed. |
| **T8-1b — Metal (Apple Silicon) backend runtime ([ADR-0420](adr/0420-metal-backend-runtime-t8-1b.md))** — replaces the T8-1 scaffold's `-ENOSYS` C stubs with three Obj-C++ `.mm` TUs (`common.mm`, `picture_metal.mm`, `kernel_template.mm`) driving `Metal.framework` via Obj-C++ ARC. `MTLCreateSystemDefaultDevice` / `MTLCopyAllDevices`, Apple-Family-7 gate, `MTLResourceStorageModeShared` zero-copy buffers, private MTLCommandQueue + two MTLSharedEvent handles per consumer. | PR #764 (`feat/metal-runtime-t8-1b`, 2026-05-11). | [ADR-0420](adr/0420-metal-backend-runtime-t8-1b.md) | macOS Metal CI lane green; subsequent PRs #765 (kernels T8-1d–j), #766 (CLI selectors, ADR-0422), #767 (IOSurface zero-copy import, ADR-0423) layered on top. Homebrew tap flipped from MoltenVK to native Metal ([formula](https://github.com/lusoris/homebrew-tap/blob/master/Formula/libvmaf.rb)). |
Expand Down
Loading