41 lines
1.6 KiB
Python
Raw Normal View History

2026-07-30 18:57:10 +02:00
import numpy as np
from tsi_sim import concurrency
from tsi_sim.config import SimConfig
def test_window_counts_partitions_all_proposals():
ws = np.array([0, 1, 2, 5, 5, 9], dtype=np.int64)
counts = concurrency.window_counts(ws, epoch_len=10, bucket=5)
assert counts.tolist() == [3, 3] # slots 0-4 -> 3, slots 5-9 -> 3
assert counts.sum() == ws.size
def test_window_counts_bucket_one_is_per_slot():
ws = np.array([0, 0, 3], dtype=np.int64)
counts = concurrency.window_counts(ws, epoch_len=4, bucket=1)
assert counts.tolist() == [2, 0, 0, 1] # slot 0 has 2 concurrent, slot 3 has 1
def test_window_counts_empty():
assert concurrency.window_counts(np.empty(0, np.int64), 10, 2).tolist() == [0, 0, 0, 0, 0]
def test_concurrency_stats_scale_with_latency():
# Bigger latency bucket => more proposals per bucket (max/mean grow roughly with L).
small = concurrency.concurrency_stats(SimConfig(n_nodes=1000, latency=2, k=32, epochs=1))
large = concurrency.concurrency_stats(SimConfig(n_nodes=1000, latency=20, k=32, epochs=1))
assert large["mean"] > small["mean"]
assert large["max"] >= small["max"]
# mean per bucket ~ bucket * (-ln(1-f))
expected = large["bucket"] * (-np.log(1 - 1 / 30))
assert abs(large["mean"] - expected) < 0.25 * expected
def test_proposal_slots_reproducible_and_sorted():
cfg = SimConfig(n_nodes=500, latency=4, k=16, epochs=1)
a = concurrency.proposal_slots(cfg, replicate=0)
b = concurrency.proposal_slots(cfg, replicate=0)
np.testing.assert_array_equal(a, b)
assert np.all(np.diff(a) >= 0)