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
69 changes: 39 additions & 30 deletions docs/adr/0787-libvmaf-api-error-path-audit.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,51 +11,60 @@

## Context

A full audit of every `VMAF_EXPORT` function in `core/include/libvmaf/` was requested to
establish ground truth on: (1) the error-return convention, (2) consistent use of errno
codes, (3) silent-error paths (returning 0 on real failure), (4) void functions that mask
errors, and (5) cross-backend parity. See Research-0787 for the full findings.
A full audit of every `VMAF_EXPORT` function in `core/include/libvmaf/` was
requested to establish ground truth on: (1) the error-return convention,
(2) consistent use of errno codes, (3) silent-error paths (returning 0 on
real failure), (4) void functions that mask errors, and (5) cross-backend
parity. See Research-0787 for the full findings.

## Decision

The audit confirms the following convention is in use and should be maintained across all
backends: `0` on success, `< 0` negative errno on failure. No VMAF-specific error code
namespace is needed.
The audit confirms the following convention is in use and should be maintained
across all backends: `0` on success, `< 0` negative errno on failure. No
VMAF-specific error code namespace is needed.

Six defects were identified (see Research-0787 §6). The following fixes are approved and
should be addressed in a follow-up implementation PR:
Six defects were identified (see Research-0787 §6). The following fixes are
approved and should be addressed in a follow-up implementation PR:

1. `vmaf_write_output_with_format()` returns `-EINVAL` for filesystem errors — fix to
return `-errno`.
2. `vmaf_cuda_state_init()` returns `-EINVAL` for driver-not-found (should be `-ENOSYS`)
and no-GPU (should be `-ENODEV`).
1. `vmaf_write_output_with_format()` returns `-EINVAL` for filesystem errors
— fix to return `-errno`.
2. `vmaf_cuda_state_init()` returns `-EINVAL` for driver-not-found (should
be `-ENOSYS`) and no-GPU (should be `-ENODEV`).
3. `vmaf_close()` drops return values of `vmaf_framesync_destroy()`,
`vmaf_thread_pool_wait()`, and `vmaf_picture_unref()` — fix with `(void)` casts.
4. `vmaf_cuda_state_free()` has mismatched signature vs. all other backends (single-ptr,
int-return) — tracked for a future ABI-bump PR; current callers are warned.
5. `vmaf_cuda_preallocate_pictures()` lacks the `-EBUSY` guard present in SYCL/Vulkan.
6. `vmaf_init()` funnels all sub-init errors to `-ENOMEM` — fix to propagate `err`.
`vmaf_thread_pool_wait()`, and `vmaf_picture_unref()` — fix with
`(void)` casts.
4. `vmaf_cuda_state_free()` has mismatched signature vs. all other backends
(single-ptr, int-return) — tracked for a future ABI-bump PR; current
callers are warned.
5. `vmaf_cuda_preallocate_pictures()` lacks the `-EBUSY` guard present in
SYCL/Vulkan.
6. `vmaf_init()` funnels all sub-init errors to `-ENOMEM` — fix to
propagate `err`.

## Alternatives considered

- Introducing a VMAF-specific error code enum: rejected. The errno convention is already
established throughout the codebase and matches the FFmpeg filter integration contract.
A parallel enum would require a translation layer.
- Introducing a VMAF-specific error code enum: rejected. The errno convention
is already established throughout the codebase and matches the FFmpeg filter
integration contract. A parallel enum would require a translation layer.

- Treating the `state_free` signature mismatch as a no-op: rejected. The single-pointer
convention forces callers to manually null the handle. The double-pointer convention
(used by SYCL, HIP, Metal, Vulkan) is strictly safer. Fixing CUDA requires an ABI-break
PR with a version bump.
- Treating the `state_free` signature mismatch as a no-op: rejected. The
single-pointer convention forces callers to manually null the handle. The
double-pointer convention (used by SYCL, HIP, Metal, Vulkan) is strictly
safer. Fixing CUDA requires an ABI-break PR with a version bump.

## Consequences

- An implementation PR will address items 1, 2, 3, 5, and 6 without ABI impact.
- Item 4 (`vmaf_cuda_state_free` ABI break) is deferred to the next major ABI bump.
- An implementation PR will address items 1, 2, 3, 5, and 6 without ABI
impact.
- Item 4 (`vmaf_cuda_state_free` ABI break) is deferred to the next major
ABI bump.
- The audit output is captured as Research-0787 under `docs/research/`.

## References

- Research-0787: `docs/research/research-0787-libvmaf-api-error-path-audit.md`
- Research-0787:
`docs/research/research-0787-libvmaf-api-error-path-audit.md`
- Files audited: `core/include/libvmaf/*.h`, `core/src/libvmaf.c`,
`core/src/cuda/common.c`, `core/src/sycl/common.cpp`, `core/src/hip/common.c`,
`core/src/picture.c`, `core/src/feature/feature_collector.c`
`core/src/cuda/common.c`, `core/src/sycl/common.cpp`,
`core/src/hip/common.c`, `core/src/picture.c`,
`core/src/feature/feature_collector.c`
30 changes: 18 additions & 12 deletions docs/adr/0788-doxygen-thread-safety-tags.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# ADR-0788: Doxygen @brief/@param/@return and @thread-safety tags on all public C-API functions
# ADR-0788: Doxygen doc-comment and @thread-safety tags on public C-API

| Field | Value |
|----------|-----------------------------------|
Expand All @@ -14,17 +14,22 @@ found that several public functions were missing Doxygen `@brief`, `@param`, and
which forced readers to hunt through implementation code to determine whether
concurrent use was safe. The rule adopted here is: one VmafContext per thread —
a VmafContext is not thread-safe because the internal feature-extractor pipeline
shares per-context state (scheduler queue, score cache, picture pool) that is not
protected by fine-grained locking. Callers that want parallel scoring create
shares per-context state (scheduler queue, score cache, picture pool) that is
not protected by fine-grained locking. Callers that want parallel scoring
create
independent VmafContexts.

The gaps existed in:
- `picture.h` — `vmaf_picture_alloc`, `vmaf_picture_unref` (no Doxygen at all)
- `feature.h` — `vmaf_feature_dictionary_set`, `vmaf_feature_dictionary_free` (no Doxygen)
- `model.h` — all eight model/collection load/destroy/overload functions (no Doxygen)
- `libvmaf.h` — `vmaf_version` (thin comment, no `@brief`/`@return`); all other functions
had Doxygen but no `@thread-safety` tag
- `dnn.h` — `vmaf_dnn_session_close` (no Doxygen block)

- `picture.h` — `vmaf_picture_alloc`, `vmaf_picture_unref` (no Doxygen at
all)
- `feature.h` — `vmaf_feature_dictionary_set`,
`vmaf_feature_dictionary_free` (no Doxygen)
- `model.h` — all eight model/collection load/destroy/overload functions
(no Doxygen)
- `libvmaf.h` — `vmaf_version` (thin comment, no `@brief`/`@return`); all
other functions had Doxygen but no `@thread-safety` tag
- `dnn.h` — `vmaf_dnn_session_close` (no Doxygen block)

The GPU-backend headers (`libvmaf_cuda.h`, `libvmaf_sycl.h`, `libvmaf_hip.h`,
`libvmaf_vulkan.h`, `libvmaf_metal.h`, `libvmaf_mcp.h`) were already adequately
Expand All @@ -48,6 +53,7 @@ is safe to call from any thread.

## References

- req: "Sweep `core/include/libvmaf/*.h` for missing Doxygen comments on public
functions. Per PR #115 thread-safety audit: also add `@thread-safety` tags noting
'not thread-safe; one VmafContext per thread' per ADR-0777 follow-up #1."
- req: "Sweep `core/include/libvmaf/*.h` for missing Doxygen comments on
public functions. Per PR #115 thread-safety audit: also add
`@thread-safety` tags noting 'not thread-safe; one VmafContext per
thread' per ADR-0777 follow-up #1."
4 changes: 3 additions & 1 deletion docs/adr/0848-per-surface-doc-compliance-audit.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ surfaced for immediate action.
until Issue A is resolved.

**Neutral follow-ups**:

- Open GitHub issues for Issue A (Vulkan removal docs cleanup) and Issue B
(VmafLegacyQualityRunner deprecations.md entry).
- ADR citation correction: `docs/metrics/features.md` footnote 6 cites
Expand All @@ -61,7 +62,8 @@ until Issue A is resolved.

## References

- Research-0848: `docs/research/research-0848-per-surface-doc-compliance-audit-20260529.md`
- Research-0848:
`docs/research/research-0848-per-surface-doc-compliance-audit-20260529.md`
- CLAUDE.md §12 r10 (per-surface doc bar)
- ADR-0100: project-wide doc substance rule
- ADR-0726: Vulkan backend removal (PR #47)
Expand Down
7 changes: 4 additions & 3 deletions docs/research/0116-float-adm-avx2-512-f2-f3-precision.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,9 @@ per-TU carve-out with `-ffp-contract=off` already present in

## Fix summary

- **F2**: Replace store-to-temp loops with `_mm256_cvtps_pd` +
`hadd_pd4()` (AVX2) and `_mm512_extractf32x4_ps` + `_mm256_cvtps_pd`
+ `hadd_pd4()` (AVX-512). No float-precision intermediate stores
- **F2**: Replace store-to-temp loops with `_mm256_cvtps_pd` plus
`hadd_pd4()` (AVX2) and `_mm512_extractf32x4_ps` plus `_mm256_cvtps_pd`
plus `hadd_pd4()` (AVX-512). No float-precision intermediate stores
anywhere in the reduction paths.
- **F3**: Move both TUs to isolated `x86_float_adm_avx2_lib` /
`x86_float_adm_avx512_lib` static libraries in `core/src/meson.build`
Expand All @@ -78,6 +78,7 @@ is structurally identical to the AVX2 fix and compiles clean under
`-mavx512f`.

Cross-backend reproducer:

```bash
vmaf --cpumask 255 --reference src01_hrc00_576x324.yuv \
--distorted src01_hrc01_576x324.yuv \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,14 +90,22 @@ log-format note in `docs/backends/cuda/overview.md` should note the removed

**PR**: `e9d265657` `feat(core)!: drop Vulkan backend (BREAKING, ADR-0726)`
**Surfaces removed**:

- Public header `core/include/libvmaf/libvmaf_vulkan.h`
- CLI flags `--backend vulkan`, `--vulkan_device <N>`, `--vulkan-require-fp64`
- CLI flags `--backend vulkan`, `--vulkan_device <N>`,
`--vulkan-require-fp64`
- Meson option `enable_vulkan`

**Missing doc updates**:
1. `/home/kilian/dev/vmaf/.claude/worktrees/agent-a29d1011065d0eb5e/docs/backends/vulkan/overview.md` — still describes Vulkan as a working backend with full kernel coverage; should be replaced with a removal notice.
2. `/home/kilian/dev/vmaf/.claude/worktrees/agent-a29d1011065d0eb5e/docs/metrics/features.md` — every extractor row lists "Vulkan" in the backends column; should be struck or annotated as removed.
3. `/home/kilian/dev/vmaf/.claude/worktrees/agent-a29d1011065d0eb5e/docs/development/build-flags.md` — `enable_vulkan` row describes the backend as functional when enabled; should show "Removed (ADR-0726)".

1. `docs/backends/vulkan/overview.md` — still describes Vulkan as a
working backend with full kernel coverage; should be replaced with a
removal notice.
2. `docs/metrics/features.md` — every extractor row lists "Vulkan" in
the backends column; should be struck or annotated as removed.
3. `docs/development/build-flags.md` — `enable_vulkan` row describes
the backend as functional when enabled; should show
"Removed (ADR-0726)".

**Note**: PR #123 partially addressed this by updating Helm chart docs and
adding a removal notice to `docs/development/gpu-scheduling.md` and
Expand All @@ -111,8 +119,12 @@ errors or runtime failures).
**Surface**: `VmafLegacyQualityRunner` Python quality runner removed from
`compat/python-vmaf/core/quality_runner.py` (BREAKING).
**Missing**:
1. No entry in `/home/kilian/dev/vmaf/.claude/worktrees/agent-a29d1011065d0eb5e/docs/development/deprecations.md` — the deprecations file has a structured format for removals (see the "Legacy native build modes" entry); `VmafLegacyQualityRunner` should appear there.
2. No migration notice in `docs/usage/python.md` or `docs/api/` pointing users to `VmafQualityRunner`.

1. No entry in `docs/development/deprecations.md` — the deprecations file
has a structured format for removals (see the "Legacy native build
modes" entry); `VmafLegacyQualityRunner` should appear there.
2. No migration notice in `docs/usage/python.md` or `docs/api/` pointing
users to `VmafQualityRunner`.
**Note**: ADR-0749 documents the decision and migration path (`VmafQualityRunner`),
but ADRs are not user-facing docs.
**Severity**: Medium (BREAKING Python API removal; affects users who import
Expand All @@ -125,10 +137,14 @@ but ADRs are not user-facing docs.
### Issue A — Update Vulkan removal docs (post-PR #47 debt)

Files to update:
- `docs/backends/vulkan/overview.md` — replace body with removal notice + pointer to ADR-0726

- `docs/backends/vulkan/overview.md` — replace body with removal notice +
pointer to ADR-0726
- `docs/backends/vulkan/moltenvk.md` — same
- `docs/metrics/features.md` — remove "Vulkan" from every backend column; add footnote "Vulkan backend removed in ADR-0726"
- `docs/development/build-flags.md` — replace `enable_vulkan` row with "Removed (ADR-0726)"
- `docs/metrics/features.md` — remove "Vulkan" from every backend column;
add footnote "Vulkan backend removed in ADR-0726"
- `docs/development/build-flags.md` — replace `enable_vulkan` row with
"Removed (ADR-0726)"

### Issue B — Add VmafLegacyQualityRunner to deprecations.md (post-PR #87 debt)

Expand Down
1 change: 0 additions & 1 deletion scripts/ci/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ until master is fixed.

| `coverage-check.sh` | `tests-and-quality-gates.yml` — `Enforce coverage thresholds` step on both `coverage-cpu` and `coverage-gpu` (advisory) jobs | The CLI shape (`coverage-check.sh <gcovr-summary.json> <overall_min%> <critical_min%>`) and the in-script `PER_FILE_MIN` map are the gate definition. Every entry in `PER_FILE_MIN` must cite the ADR that justifies the lower bar ([ADR-0114](../../docs/adr/0114-coverage-gate-per-file-overrides.md)). Audit cadence + tighten/keep/remove rule codified in [ADR-0881](../../docs/adr/0881-coverage-overrides-audit-2026-05-30.md). Gcovr's emit-path format (currently `core/src/...` relative to repo root) is the join-key with `PER_FILE_MIN`; if a future gcovr upgrade changes that format, the override silently stops applying and the global 85 % gate kicks in — the per-line "min XX%" output is the canary. |


## Calibration table contract (ADR-0234)

`gpu_ulp_calibration.yaml` is the single source of truth for
Expand Down
Loading