From 9010d417e2b541b1080358dc2991b06a927b49e0 Mon Sep 17 00:00:00 2001 From: local Date: Thu, 5 Nov 2026 10:50:31 +0000 Subject: [PATCH] simple: validate exact expected coverage sequence in step() --- simple/ovl.py | 13 +++++++------ tests/simple/test_ovl.py | 13 +++++++++++++ 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/simple/ovl.py b/simple/ovl.py index 94f9eb28..4a19d1dc 100644 --- a/simple/ovl.py +++ b/simple/ovl.py @@ -304,13 +304,14 @@ def next_target(cursor, ranges): def step(model, opt, b, ctl): ids = b["target_ids"][b["mask"]] ranges = excluded(ctl) - first = next_target(ctl["cursor"], ranges) - last = first + ids.numel() - 1 - for s, n in ranges: # an excluded document inside the batch's span widens it by exactly its size - if first < s <= last: - last += n - if ids.numel() == 0 or ids[0].item() != first or ids[-1].item() != last: + expected, cursor = [], ctl["cursor"] + for _ in range(ids.numel()): # the exact id sequence: consecutive, skipping each excluded range + cursor = next_target(cursor, ranges) + expected.append(cursor) + cursor += 1 + if ids.numel() == 0 or ids.tolist() != expected: raise SystemExit(f"coverage error at cursor {ctl['cursor']}") # gap, repeat or reorder + last = expected[-1] for g in opt.param_groups: g["lr"] = learning_rate(ctl) x, y, m = (b[k].to(DEV, non_blocking=True) for k in ("inputs", "targets", "mask")) diff --git a/tests/simple/test_ovl.py b/tests/simple/test_ovl.py index 90d851f0..cb09c483 100644 --- a/tests/simple/test_ovl.py +++ b/tests/simple/test_ovl.py @@ -185,6 +185,19 @@ def test_gap_of_wrong_size_or_place_fails(self): with self.assertRaisesRegex(SystemExit, "coverage error"): ovl.step(self.model, self.opt, self.batch(ids), self.ctl(10, exclude)) + def test_middle_duplicate_fails(self): + with self.assertRaisesRegex(SystemExit, "coverage error"): + ovl.step(self.model, self.opt, self.batch([10, 11, 11, 13]), self.ctl(10)) + + def test_middle_reorder_fails(self): + with self.assertRaisesRegex(SystemExit, "coverage error"): + ovl.step(self.model, self.opt, self.batch([10, 12, 11, 13]), self.ctl(10)) + + def test_wrong_excluded_middle_range_fails(self): + # 12 is excluded but trained, while 11 (not excluded) is skipped; endpoints still match. + with self.assertRaisesRegex(SystemExit, "coverage error"): + ovl.step(self.model, self.opt, self.batch([10, 12, 13, 14]), self.ctl(10, [[12, 1]])) + def test_exclusion_only_applies_to_its_phase(self): c = {"phase": "conversation", "global_step": 0, "cursor": 10, "exclude": {"wikipedia": [[12, 3]]}} with self.assertRaisesRegex(SystemExit, "coverage error"):