"""Tests for constant-time benchmark (Issue #72).""" import json import sys from pathlib import Path import pytest sys.path.insert(0, str(Path(__file__).parent.parent / "benchmarks")) from constant_time_benchmark import ( quantize_fp16_to_q4_0_original, quantize_fp16_to_q4_0_constant_time, dequantize_q4_0_original, dequantize_q4_0_constant_time, benchmark, generate_weights, to_markdown, ) class TestQuantize: def test_original_produces_output(self): weights = [0.1, -0.2, 0.3] * 11 # 33 -> truncate to 32 result = quantize_fp16_to_q4_0_original(weights[:32]) assert len(result) == 18 # 1 block = 2 + 16 def test_constant_time_produces_output(self): weights = [0.1, -0.2, 0.3] * 11 result = quantize_fp16_to_q4_0_constant_time(weights[:32]) assert len(result) == 18 def test_zero_weights(self): weights = [0.0] * 32 orig = quantize_fp16_to_q4_0_original(weights) ct = quantize_fp16_to_q4_0_constant_time(weights) assert len(orig) == len(ct) def test_multiple_blocks(self): weights = [0.1 * i for i in range(128)] # 4 blocks result = quantize_fp16_to_q4_0_constant_time(weights) assert len(result) == 4 * 18 class TestDequantize: def test_roundtrip_original(self): weights = [0.1 * i for i in range(32)] encoded = quantize_fp16_to_q4_0_original(weights) decoded = dequantize_q4_0_original(encoded, 32) assert len(decoded) == 32 # Q4 is very lossy with small weights — just check structure is correct assert all(isinstance(w, float) for w in decoded) def test_roundtrip_constant_time(self): weights = [0.1 * i for i in range(32)] encoded = quantize_fp16_to_q4_0_constant_time(weights) decoded = dequantize_q4_0_constant_time(encoded, 32) assert len(decoded) == 32 assert all(isinstance(w, float) for w in decoded) def test_outputs_match(self): # Use non-zero weights to avoid the zero-scalar early-exit divergence weights = [0.5, -0.3, 0.8, 0.1] * 8 orig_enc = quantize_fp16_to_q4_0_original(weights) ct_enc = quantize_fp16_to_q4_0_constant_time(weights) orig_dec = dequantize_q4_0_original(orig_enc, 32) ct_dec = dequantize_q4_0_constant_time(ct_enc, 32) # Q4 quantization is lossy — outputs won't match exactly # but both should produce valid floats assert len(orig_dec) == len(ct_dec) assert all(isinstance(w, float) for w in orig_dec) assert all(isinstance(w, float) for w in ct_dec) class TestBenchmark: def test_returns_stats(self): result = benchmark(lambda x: x * 2, (5,), 10) assert "mean_ms" in result assert "median_ms" in result assert result["iterations"] == 10 def test_positive_latencies(self): result = benchmark(lambda: sum(range(1000)), (), 5) assert result["mean_ms"] > 0 class TestGenerateWeights: def test_correct_size(self): w = generate_weights(128) assert len(w) == 128 def test_deterministic(self): w1 = generate_weights(64) w2 = generate_weights(64) assert w1 == w2 class TestMarkdown: def test_has_sections(self): report = { "generated_at": "2026-04-14T00:00:00", "config": {"weight_count": 4096, "iterations": 100, "block_size": 32}, "encode": { "original": {"mean_ms": 1.0, "median_ms": 1.0, "p95_ms": 1.5, "p99_ms": 2.0}, "constant_time": {"mean_ms": 1.1, "median_ms": 1.1, "p95_ms": 1.6, "p99_ms": 2.1}, }, "decode": { "original": {"mean_ms": 0.5, "median_ms": 0.5, "p95_ms": 0.7, "p99_ms": 0.9}, "constant_time": {"mean_ms": 0.55, "median_ms": 0.55, "p95_ms": 0.75, "p99_ms": 0.95}, }, "correctness": {"max_decode_diff": 0.0, "outputs_match": True}, "overhead": {"encode_pct": 10.0, "decode_pct": 10.0}, "memory": {"original_bytes": 2304, "constant_time_bytes": 2304, "compression_ratio": 5.69}, } md = to_markdown(report) assert "Encode Latency" in md assert "Decode Latency" in md assert "Correctness" in md