From fa1a0253df6cd41b79d80f081a68c53e46070682 Mon Sep 17 00:00:00 2001 From: Oleksandr Pavlyk <21087696+oleksandr-pavlyk@users.noreply.github.com> Date: Fri, 26 Jun 2026 16:40:59 -0500 Subject: [PATCH] Validate bulk binary sizes as integral metadata Reject boolean and floating-point values for int64 bulk binary sizes instead of silently converting them with int(). Keep integer strings accepted for existing NVBench JSON compatibility, and add regression coverage for valid and malformed size payloads. --- python/scripts/nvbench_compare.py | 10 ++++++++++ python/test/test_nvbench_compare.py | 25 +++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/python/scripts/nvbench_compare.py b/python/scripts/nvbench_compare.py index 4398370..cd17207 100644 --- a/python/scripts/nvbench_compare.py +++ b/python/scripts/nvbench_compare.py @@ -845,6 +845,16 @@ def extract_binary_filename(summary): def extract_binary_size(summary): value = extract_summary_data_value(summary, "size", "int64") + if isinstance(value, bool): + raise ValueError( + f"summary {summary.get('tag', '')!r} field 'size' " + f"value {value!r} is not an int64" + ) + if isinstance(value, float): + raise ValueError( + f"summary {summary.get('tag', '')!r} field 'size' " + f"value {value!r} is not an int64" + ) try: return int(value) except (TypeError, ValueError) as exc: diff --git a/python/test/test_nvbench_compare.py b/python/test/test_nvbench_compare.py index 57848bc..94fcca2 100644 --- a/python/test/test_nvbench_compare.py +++ b/python/test/test_nvbench_compare.py @@ -114,6 +114,13 @@ def make_binary_summary(nvbench_compare, tag, filename, size): } +def make_raw_binary_size_summary(nvbench_compare, value): + return { + "tag": nvbench_compare.SAMPLE_TIMES_TAG, + "data": [{"name": "size", "type": "int64", "value": value}], + } + + def make_reader_for_roots(ref_root, cmp_root): def read_file(path): if path == "ref.json": @@ -463,6 +470,24 @@ def test_gpu_timing_data_loads_samples_and_frequencies_lazily( assert reader_calls == [str(samples_file), str(freqs_file)] +@pytest.mark.parametrize("value", [3, "3"]) +def test_extract_binary_size_accepts_integral_values(value, nvbench_compare): + assert ( + nvbench_compare.extract_binary_size( + make_raw_binary_size_summary(nvbench_compare, value) + ) + == 3 + ) + + +@pytest.mark.parametrize("value", [True, False, 3.0, 3.5, "3.5"]) +def test_extract_binary_size_rejects_non_integral_values(value, nvbench_compare): + with pytest.raises(ValueError, match="is not an int64"): + nvbench_compare.extract_binary_size( + make_raw_binary_size_summary(nvbench_compare, value) + ) + + def test_compare_benches_collects_bulk_debug_rows(tmp_path, nvbench_compare): run_data = make_comparison_run_data(nvbench_compare) ref_samples_file = tmp_path / "ref-samples.bin"