Repository navigation
fix(ci): build the clang-tidy lanes without LTO so the gate can pass at all - #1326
Merged
Merged
Conversation
…at all Since PR #1290 merged, the required Tidy Changed and Tidy Ratchet gates failed on every C/C++ pull request regardless of its diff. core/meson.build's default_options gained b_lto_threads=4 (ADR-1172) to cap link-time parallelism; meson renders that as GCC's -flto=4, the tidy lane's gcc-14 build writes it into compile_commands.json, and clang-tidy parses those entries with clang, which rejects the argument outright: clang: error: unsupported argument '4' to option '-flto=' so every translation unit ended in "1 error generated". Reproduced against a stock master build: 1257 -flto=4 entries, and clang-tidy on core/src/picture.c reports "Error while processing". Both tidy builds now configure with -Db_lto=false. They exist only to emit compile_commands.json and the generated headers, so LTO buys nothing there, and the SYCL tidy lane already configured that way for its own toolchain reason. After the change compile_commands.json holds zero -flto entries and the same file processes cleanly (459 suppressed, no error). docs/state.md: T-TIDY-CHANGED-LTO-FLAG-2026-09-05 (Recently closed).
lusoris
marked this pull request as ready for review
September 5, 2026 20:33
lusoris
added a commit
that referenced
this pull request
Sep 5, 2026
`core/src/feature/feature_extractor.h` was the last file this branch touches that still carried clang-tidy findings (8). clang-tidy has no compile command for a header and falls back to the nearest matching TU's — `feature_extractor.cpp` — so it parses this C header as C++ and proposes rewrites that would break the roughly one hundred C translation units which include it: `<cstdint>` / `<cstdlib>` for the C headers, `using` for the `typedef struct`s, a C23 fixed underlying type on the two flag enums (which MSVC does not document under `/std:clatest`, and the Windows MSVC build is a required check), and a rename of the upstream `__VMAF_FEATURE_EXTRACTOR_H__` include guard that every other header under `core/src/` also uses. Discharged with one file-scoped `NOLINTBEGIN` / `NOLINTEND` bracket — the shape ADR-1138 prescribes and `core/test/test_feature_extractor.c` already uses — whose justification and its ADR-0141 / ADR-1138 / ADR-0148 / ADR-0150 citations live inside the marker's own block comment, where `scripts/ci/tidy-ratchet.py::count_uncited_nolints` looks for them. No declaration, macro, type or guard changed, so no includer is affected. The `-Db_lto=false` half of the original commit is dropped: PR #1326 landed the identical fix on master while this branch was in review. Verified: clang-tidy 22.1.8 against a CPU-only build dir configured like the CI lane reports 0 warnings, 0 errors, exit 0 for all four CI-linted files (`feature_extractor.cpp`, `feature_extractor.h`, `libvmaf.c`, `test_feature_extractor.c`); `count_uncited_nolints` on the header returns 0. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
lusoris
added a commit
that referenced
this pull request
Sep 5, 2026
`core/src/feature/feature_extractor.h` was the last file this branch touches that still carried clang-tidy findings (8). clang-tidy has no compile command for a header and falls back to the nearest matching TU's — `feature_extractor.cpp` — so it parses this C header as C++ and proposes rewrites that would break the roughly one hundred C translation units which include it: `<cstdint>` / `<cstdlib>` for the C headers, `using` for the `typedef struct`s, a C23 fixed underlying type on the two flag enums (which MSVC does not document under `/std:clatest`, and the Windows MSVC build is a required check), and a rename of the upstream `__VMAF_FEATURE_EXTRACTOR_H__` include guard that every other header under `core/src/` also uses. Discharged with one file-scoped `NOLINTBEGIN` / `NOLINTEND` bracket — the shape ADR-1138 prescribes and `core/test/test_feature_extractor.c` already uses — whose justification and its ADR-0141 / ADR-1138 / ADR-0148 / ADR-0150 citations live inside the marker's own block comment, where `scripts/ci/tidy-ratchet.py::count_uncited_nolints` looks for them. No declaration, macro, type or guard changed, so no includer is affected. The `-Db_lto=false` half of the original commit is dropped: PR #1326 landed the identical fix on master while this branch was in review. Verified: clang-tidy 22.1.8 against a CPU-only build dir configured like the CI lane reports 0 warnings, 0 errors, exit 0 for all four CI-linted files (`feature_extractor.cpp`, `feature_extractor.h`, `libvmaf.c`, `test_feature_extractor.c`); `count_uncited_nolints` on the header returns 0. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
lusoris
added a commit
that referenced
this pull request
Sep 5, 2026
`core/src/feature/feature_extractor.h` was the last file this branch touches that still carried clang-tidy findings (8). clang-tidy has no compile command for a header and falls back to the nearest matching TU's — `feature_extractor.cpp` — so it parses this C header as C++ and proposes rewrites that would break the roughly one hundred C translation units which include it: `<cstdint>` / `<cstdlib>` for the C headers, `using` for the `typedef struct`s, a C23 fixed underlying type on the two flag enums (which MSVC does not document under `/std:clatest`, and the Windows MSVC build is a required check), and a rename of the upstream `__VMAF_FEATURE_EXTRACTOR_H__` include guard that every other header under `core/src/` also uses. Discharged with one file-scoped `NOLINTBEGIN` / `NOLINTEND` bracket — the shape ADR-1138 prescribes and `core/test/test_feature_extractor.c` already uses — whose justification and its ADR-0141 / ADR-1138 / ADR-0148 / ADR-0150 citations live inside the marker's own block comment, where `scripts/ci/tidy-ratchet.py::count_uncited_nolints` looks for them. No declaration, macro, type or guard changed, so no includer is affected. The `-Db_lto=false` half of the original commit is dropped: PR #1326 landed the identical fix on master while this branch was in review. Verified: clang-tidy 22.1.8 against a CPU-only build dir configured like the CI lane reports 0 warnings, 0 errors, exit 0 for all four CI-linted files (`feature_extractor.cpp`, `feature_extractor.h`, `libvmaf.c`, `test_feature_extractor.c`); `count_uncited_nolints` on the header returns 0. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
lusoris
added a commit
that referenced
this pull request
Sep 5, 2026
…del options (ADR-1183) (#1312) * fix(cuda): make the default model run on CUDA — cambi context push, option validation, CPU-twin dispatch (ADR-1183) - integer_cambi_cuda.c: push/pop the CUDA context around the submit path (the DtoH readback ran with no current context: CUDA_ERROR_INVALID_CONTEXT), mirror the CPU cambi option table (cambi_high_res_speedup/hrs, vlt, cmxv) and the TVI table init from cambi.c so the emitted feature name matches the model's. - integer_motion_cuda.c: route scores through the feature_name_dict so motion3 emits integer_motion3_mmxv_18 like the CPU twin. - feature_extractor.cpp: an opts_dict key the chosen extractor does not declare is an error (-EINVAL, logged) instead of being silently dropped. - libvmaf.c: when a GPU twin lacks an option the model sets, resolve the CPU twin for that feature and log it (ADR-1183) — adm3 of vmaf_v1.0.16_3d0h runs on the CPU under CUDA/SYCL/HIP until the csf_mode port lands (docs/state.md T-GPU-ADM-CSF-MODE-NOT-PORTED-2026-09-05). - python/test/cuda_default_model_test.py (new, skips without CUDA); .gitleaks.toml allowlists VMAF pooled-metric names (the test's `<name>_key = "<metric>"` lines tripped generic-api-key on every PR because gitleaks scans all branches). Verified on the RTX 4090: 576x324 and 1080p reproducers exit 0; adm3 bit-exact vs CPU, cambi delta 2.66e-3 / 1.76e-2 (tracked), v0.6.1 unchanged, typo option rejected; golden gate 271 passed / 12 skipped / 0 failed. * fix(core): keep the model-option gating inside the tidy budget The ADR-1183 GPU-twin fallback pushed vmaf_use_features_from_model past the readability-function-size threshold and the two new test cases in test_feature_extractor.c added eight uncited modernize-use-nullptr findings, so the whole-tree ratchet (ADR-1142) refused the PR. - The fallback moves into fex_honouring_model_options(), a helper that returns the extractor able to honour every option the model sets for one feature (the GPU twin, or the CPU twin with an INFO line, or NULL when nothing provides the feature). vmaf_use_features_from_model is back under the threshold and reads as one loop again. - The new tests' NULL arguments and returns carry the ADR-1138 citation the other C TUs use (MSVC /std:clatest has no C nullptr). - feature_extractor.cpp lost four findings to the option-validation refactor, so its baseline entry is tightened 54 -> 50 with the count CI measured (the local clang is a different version and is not the authority). Behaviour is unchanged: the CUDA default-model run still exits 0 with the CPU dispatch line for adm3, test_feature_extractor is 13/13. * test(core): clear clang-tidy debt in test_feature_extractor.c (59 -> 0) The touched-file cleanup rule (ADR-0141) makes this PR inherit every pre-existing clang-tidy finding in the test TUs it edits. Discharge all 59 in `core/test/test_feature_extractor.c`: * modernize-use-nullptr (54): replace the 17 scattered, partly stale `NOLINTNEXTLINE` markers (several of which sat above comment lines and suppressed nothing) with the single file-scoped `NOLINTBEGIN(modernize-use-nullptr)` / `NOLINTEND` bracket that ADR-1138 prescribes and that `core/src/libvmaf.c`, `core/test/test_output.c` and the other C TUs already use. The TU keeps spelling the null pointer constant `NULL`: the required MSVC C lane has no documented C `nullptr`, and upstream parity matters for the sync story. * readability-function-size (5): split the oversized cases into one behaviour per test instead of suppressing them. - `test_feature_extractor_flush` and `test_feature_extractor_initialization_options` now share a `FexFixture` (context + ref/dist pictures + collector) with `fex_fixture_open` / `fex_fixture_close` / `fex_fixture_extract_two_frames_and_flush` helpers. - `test_fex_vector_dedup_by_provided_feature_name` gained a `fex_vector_create_and_append` helper. - `test_feature_extractor_supports_options_helper` split into `test_supports_options_empty_dict`, `_known_key`, `_unknown_key_reports_missing`, `_alias_key` and `_null_extractor`. - the SpEED GPU-twin registry guard moved out of `test_get_feature_extractor_by_name_and_feature_name` into `test_speed_gpu_twins_resolve_by_name`, which also keeps that case inside budget in an all-backends build. - `run_tests` now delegates to `run_registry_tests`, `run_context_tests` and `run_option_tests`, the grouping pattern `test_cli_parse.c` and `test_iqa_helpers.c` already use. No assertion was dropped: 17 cases / 79 assertions become 18 cases / 88 assertions, and the conditions folded into the fixture helpers are still checked there and reported through the fixture's status. The Netflix golden assertions are untouched, and the PR's CUDA CAMBI fix is unaffected. Verified: `clang-tidy -p core/build core/test/test_feature_extractor.c` 59 -> 0 warnings (clang-tidy 22.1.8); `core/build/test/test_feature_extractor` 18/18 pass; `meson test -C core/build --suite fast --no-suite gpu` 115/115 Ok; `pre-commit run --files` clean. Baseline tightened in `scripts/ci/tidy-baseline-cpu.json` (entry removed, total 3060 -> 3001) per the ADR-1142 ratchet, and a rebase note recorded for the new group runners and the NOLINT bracket. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * refactor(core): clear clang-tidy debt in feature_extractor.cpp (51 -> 0) The touched-file cleanup rule (ADR-0141) makes this PR inherit every pre-existing clang-tidy finding in the TUs it edits. Discharge all 51 in `core/src/feature/feature_extractor.cpp` with no `NOLINT`: * modernize-use-nullptr (29): this TU is C++, so ADR-1138's keep-`NULL` exemption (which exists for the required MSVC C lane and upstream C parity) does not apply — spell the null pointer constant `nullptr`. Prose in comments still says "NULL" where it refers to the C twin. * misc-const-correctness (14): `const` on the error-code locals, on `ctx_array_sz`, and on the three read-only pointees (`ref_priv` in extract, `fex` in `vmaf_fex_ctx_pool_release` / `_flush`). * misc-use-anonymous-namespace (5): move `feature_extractor_list[]`, `vmaf_fex_ctx_parse_options`, `get_fex_list_entry`, `ctx_pool_ensure_slot_ctx` and `ctx_pool_claim_slot` out of `static` and into anonymous namespaces. The C twin keeps `static`. * readability-function-size (2): split rather than suppress. - `vmaf_feature_extractor_context_extract` (85 lines / 16 branches): the CUDA and HIP picture buf_type validation moves verbatim into `check_pic_buf_type(fex, ref_priv)`, which returns 0 or -EINVAL. Same predicates, same log messages, same return value. - `get_fex_list_entry` (68 lines) splits into `find_fex_list_entry` (the existing-entry lookup), `grow_fex_list` (the geometric realloc plus placement-new of the fresh slots) and `init_fex_list_slot` (capacity/condvar/ctx_list/opts_dict init, with the same unwind on each failure). The helpers return an errno; `get_fex_list_entry` still returns nullptr on any failure, which the caller still turns into -EINVAL, and `pool->cnt` is still bumped only on success. * cert-dcl03-c,misc-static-assert (1): clang-tidy 22 flags every `assert()` whose condition contains no non-constexpr call, so `assert(pool->capacity > 0)` cannot stay. Replaced with a hard `if (pool->capacity == 0) return -EINVAL;` in `grow_fex_list` — an always-on guard is strictly stronger than a check compiled out under NDEBUG, and the state is unreachable either way (`pool_create` seeds capacity = 8 and this is its only writer). `<cassert>` is now unused and dropped. Dropping `static` from the registry declaration broke the `check-dispatch-registry` pre-commit / CI gate, whose `sed` range hard-coded the `static VmafFeatureExtractor *feature_extractor_list[]` spelling; it now accepts both spellings, with a new self-test case (Test 4) covering the anonymous-namespace form. No behaviour change: the extractor registry, the context pool and the option validation this PR adds all keep their exact control flow, and the CUDA CAMBI fix is untouched. Verified: `clang-tidy -p core/build core/src/feature/feature_extractor.cpp` 51 -> 0 warnings (clang-tidy 22.1.8, CUDA-enabled build) and 0 in a CPU-only build dir matching the CI lane; `core/build/test/test_feature_extractor` 18/18 pass; `meson test -C core/build --suite fast --no-suite gpu` 115/115 Ok; `bash scripts/ci/tests/test-check-dispatch-registry.sh` 11/11 pass; `pre-commit run --files` clean. Baseline tightened in `scripts/ci/tidy-baseline-cpu.json` (entry removed, total 3001 -> 2951) per the ADR-1142 ratchet, and a rebase note recorded for the anonymous namespaces and the two function splits. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * refactor(core): clear the last clang-tidy debt in feature_extractor.h `core/src/feature/feature_extractor.h` was the last file this branch touches that still carried clang-tidy findings (8). clang-tidy has no compile command for a header and falls back to the nearest matching TU's — `feature_extractor.cpp` — so it parses this C header as C++ and proposes rewrites that would break the roughly one hundred C translation units which include it: `<cstdint>` / `<cstdlib>` for the C headers, `using` for the `typedef struct`s, a C23 fixed underlying type on the two flag enums (which MSVC does not document under `/std:clatest`, and the Windows MSVC build is a required check), and a rename of the upstream `__VMAF_FEATURE_EXTRACTOR_H__` include guard that every other header under `core/src/` also uses. Discharged with one file-scoped `NOLINTBEGIN` / `NOLINTEND` bracket — the shape ADR-1138 prescribes and `core/test/test_feature_extractor.c` already uses — whose justification and its ADR-0141 / ADR-1138 / ADR-0148 / ADR-0150 citations live inside the marker's own block comment, where `scripts/ci/tidy-ratchet.py::count_uncited_nolints` looks for them. No declaration, macro, type or guard changed, so no includer is affected. The `-Db_lto=false` half of the original commit is dropped: PR #1326 landed the identical fix on master while this branch was in review. Verified: clang-tidy 22.1.8 against a CPU-only build dir configured like the CI lane reports 0 warnings, 0 errors, exit 0 for all four CI-linted files (`feature_extractor.cpp`, `feature_extractor.h`, `libvmaf.c`, `test_feature_extractor.c`); `count_uncited_nolints` on the header returns 0. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: Lusoris <lusoris@pm.me> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The required
Tidy ChangedandTidy Ratchetgates have failed on every C/C++ pull request since #1290 merged, whatever the diff contained — the queue could not merge a single C change.Cause, and it is mine: #1290 (ADR-1172) added
b_lto_threads=4tocore/meson.build'sdefault_optionsto cap link-time parallelism on the workstation. Meson renders that as GCC's-flto=4. The tidy lane configures withCC=gcc-14, so the flag lands incompile_commands.json— and clang-tidy parses those entries with clang, which rejects the argument outright:Every translation unit therefore ended in
1 error generated, and the gate could never pass. Reproduced against a stockorigin/masterbuild: 1257-flto=4entries incompile_commands.json, andclang-tidy -p core/build core/src/picture.c→Error while processing.Both tidy builds now configure with
-Db_lto=false. They exist only to emitcompile_commands.jsonand the generated headers, so LTO buys nothing there, and the SYCL tidy lane already configured that way for its own toolchain reason. After the changecompile_commands.jsonholds zero-fltoentries and the same file processes cleanly (459 suppressed, no error). Release builds keep the ADR-1172 cap unchanged.Type
fix— CI gate unblockedChecklist
make format && make lintis green locally (pre-commit on every touched file;actionlintreports only the sevenSC2317notes that are already on master).docs/rebase-notes.mdand the workflow comment.Bug-status hygiene (ADR-0165)
docs/state.md—T-TIDY-CHANGED-LTO-FLAG-2026-09-05added to Recently closed.Netflix golden-data gate (ADR-0024)
assertAlmostEqual(...)score in the Netflix golden Python tests.Deep-dive deliverables (ADR-0108)
compile_commands.jsonafterwards, or reverting ADR-1172, would both be worse.AGENTS.mdinvariant note — no rebase-sensitive invariants: the coupling is a rebase note (any compile-commands-only build configures-Db_lto=false).changelog.d/fixed/tidy-lane-lto-flag.md.docs/rebase-notes.mdentry.Reproducer
🤖 Generated with Claude Code