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
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24937,6 +24937,15 @@ in `integer_ssim_sycl.cpp` that were accidentally dropped by PR #1095 when it ad
`enable_chroma` being present in the options table and `n_planes` being clamped to 1 in v1.


- **sycl:** Fix crashes and prediction errors when running default model `vmaf_v1.0.16_3d0h`
on Intel Arc GPUs. Fix uninitialized bounds and histogram buffer allocation in
`integer_cambi_sycl.cpp`, eliminate `double` accumulators and accessors in
`speed_chroma_sycl.cpp` and `speed_temporal_sycl.cpp` (ADR-0220 fp64-less contract),
and add `cambi_high_res_speedup` (`hrs`) option to `options_cambi_sycl` to resolve
feature dictionary naming mismatch (`-EAGAIN`). Also pass `-fp-model=precise` to
AVX2/AVX-512 static libraries under `icx` ensuring CPU golden parity. (ADR-1179)


### Fixed

- **SYCL integer_vif rd_stride OOB on odd widths** (HIGH): Both the
Expand Down
7 changes: 7 additions & 0 deletions changelog.d/fixed/sycl-v1-model-crash.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
- **sycl:** Fix crashes and prediction errors when running default model `vmaf_v1.0.16_3d0h`
on Intel Arc GPUs. Fix uninitialized bounds and histogram buffer allocation in
`integer_cambi_sycl.cpp`, eliminate `double` accumulators and accessors in
`speed_chroma_sycl.cpp` and `speed_temporal_sycl.cpp` (ADR-0220 fp64-less contract),
and add `cambi_high_res_speedup` (`hrs`) option to `options_cambi_sycl` to resolve
feature dictionary naming mismatch (`-EAGAIN`). Also pass `-fp-model=precise` to
AVX2/AVX-512 static libraries under `icx` ensuring CPU golden parity. (ADR-1179)
48 changes: 48 additions & 0 deletions core/src/feature/cambi.c
Original file line number Diff line number Diff line change
Expand Up @@ -1851,4 +1851,52 @@ int vmaf_cambi_preprocessing(const VmafPicture *image, VmafPicture *preprocessed
return cambi_preprocessing(image, preprocessed, width, height, enc_bitdepth);
}

int vmaf_cambi_init_tvi_and_vlt(int num_diffs, const uint16_t *diffs_to_consider,
double tvi_threshold, double cambi_vis_lum_threshold,
const char *cambi_eotf, const char *eotf, uint16_t *tvi_for_diff,
uint16_t *vlt_luma, uint16_t *v_band_base, uint16_t *v_band_size)
{
if (!diffs_to_consider || !tvi_for_diff || !vlt_luma || num_diffs <= 0)
return -EINVAL;

VmafLumaRange luma_range;
int err = vmaf_luminance_init_luma_range(&luma_range, 10, VMAF_PIXEL_RANGE_LIMITED);
if (err)
return err;

const char *effective_eotf = (cambi_eotf && strcmp(cambi_eotf, DEFAULT_CAMBI_EOTF) != 0) ?
cambi_eotf :
(eotf ? eotf : DEFAULT_CAMBI_EOTF);

VmafEOTF eotf_obj;
err = vmaf_luminance_init_eotf(&eotf_obj, effective_eotf);
if (err)
return err;

for (int d = 0; d < num_diffs; d++) {
tvi_for_diff[d] = (uint16_t)get_tvi_for_diff(diffs_to_consider[d], tvi_threshold, 10,
luma_range, eotf_obj);
tvi_for_diff[d] += (uint16_t)num_diffs;
}

*vlt_luma = (uint16_t)get_vlt_luma(cambi_vis_lum_threshold, luma_range, eotf_obj);

int v_lo_signed = (int)(*vlt_luma) - 3 * num_diffs + 1;
uint16_t base = v_lo_signed > 0 ? (uint16_t)v_lo_signed : 0;
int size_signed = (int)tvi_for_diff[num_diffs - 1] + 1 - (int)base;
if (size_signed <= 0) {
vmaf_log(VMAF_LOG_LEVEL_ERROR,
"cambi: v_band_size underflow (tvi_max=%u v_band_base=%u); "
"cambi_vis_lum_threshold may be too low\n",
(unsigned)tvi_for_diff[num_diffs - 1], (unsigned)base);
return -EINVAL;
}
if (v_band_base)
*v_band_base = base;
if (v_band_size)
*v_band_size = (uint16_t)size_signed;

return 0;
}

/* NOLINTEND(modernize-use-nullptr) */
17 changes: 17 additions & 0 deletions core/src/feature/cambi_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,15 @@ static inline bool cambi_validate_dimensions(unsigned w, unsigned h)
* stay numerically identical if the 4K reference resolution ever changes. */
#define CAMBI_WINDOW_DIVISOR 375

#ifndef CAMBI_HIGH_RES_SPEEDUP_THRESHOLD_1080p
#define CAMBI_HIGH_RES_SPEEDUP_THRESHOLD_1080p (1920 * 1080)
#define CAMBI_HIGH_RES_SPEEDUP_THRESHOLD_1440p (2560 * 1440)
#define CAMBI_HIGH_RES_SPEEDUP_THRESHOLD_2160p (3840 * 2160)
#endif
#ifndef CAMBI_4K_HEIGHT
#define CAMBI_4K_HEIGHT (2160)
#endif

/* Range update + derivative callback signatures (mirrors cambi.c
* internal typedefs). */
typedef void (*VmafCambiRangeUpdater)(uint16_t *arr, int left, int right);
Expand All @@ -82,6 +91,8 @@ typedef struct VmafCambiHostBuffers {
uint16_t *derivative_buffer;
int *diff_weights;
int *all_diffs;
uint16_t v_band_base;
uint16_t v_band_size;
} VmafCambiHostBuffers;

/* ----- functions exported from cambi.c (otherwise file-static) ----- */
Expand Down Expand Up @@ -128,6 +139,12 @@ void vmaf_cambi_default_callbacks(VmafCambiRangeUpdater *inc, VmafCambiRangeUpda
int vmaf_cambi_preprocessing(const VmafPicture *image, VmafPicture *preprocessed, int width,
int height, int enc_bitdepth);

/* Contrast & luminance TVI / VLT initialisation helper for GPU twins. */
int vmaf_cambi_init_tvi_and_vlt(int num_diffs, const uint16_t *diffs_to_consider,
double tvi_threshold, double cambi_vis_lum_threshold,
const char *cambi_eotf, const char *eotf, uint16_t *tvi_for_diff,
uint16_t *vlt_luma, uint16_t *v_band_base, uint16_t *v_band_size);

#ifdef __cplusplus
}
#endif
Expand Down
15 changes: 15 additions & 0 deletions core/src/feature/sycl/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,21 @@ producing silently-wrong scores without any error. This is the root cause
of the `motion_fps_weight` gap in `integer_motion_v2_sycl.cpp` closed by
PR #851-follow-up (2026-05-16).

Second instance (ADR-1179, `fix/sycl-v1-model-crash`): `options_cambi_sycl`
lacked `cambi_high_res_speedup` (`hrs`). Because that knob carries
`VMAF_OPT_FLAG_FEATURE_PARAM`, its absence changed the *serialised feature
name* — the SYCL twin emitted `cambi_cmxv_17_vlt_0.06` while the default
model `vmaf_v1.0.16_3d0h` asks for `cambi_hrs_1080_cmxv_17_vlt_0.06` — and
prediction failed with `-EAGAIN` instead of falling through to a default.
Two rebase-sensitive consequences: (1) every `VMAF_OPT_FLAG_FEATURE_PARAM`
knob of `cambi.c` must exist verbatim in `options_cambi_sycl`, and (2)
`vmaf_feature_name_dict_from_provided_features()` must run in
`init_fex_sycl` **before** `enc_width` / `enc_height` / `enc_bitdepth`
are defaulted from the picture geometry (same ordering as `cambi.c`),
otherwise the geometry defaults leak into the feature name. The TVI / VLT
tables come from the shared `vmaf_cambi_init_tvi_and_vlt()` in `cambi.c`
— do not reintroduce a private bisection in the twin.

## Per-kernel parity-test invariant (ADR-0214 + ADR-0868 + ADR-0884)

**Every shipping SYCL kernel here must have a CPU-vs-SYCL parity test
Expand Down
Loading
Loading