From ba35fb24dd8105f2b6492c103c4cb2471b15b715 Mon Sep 17 00:00:00 2001 From: eunhhu Date: Thu, 8 Oct 2026 17:04:12 +0100 Subject: Batch executor, stage 4 of design 025: a column read at affine rows in memory's order in four or eight bytes is a view of the column itself (cells_at), no copy, read only while the pass runs; what outlives the pass (a local, a set's rows and value, an append's cells, a sum's rows and e, a filter's key, a read's rows) copies it (own); knapsack 4.0% fewer instructions, 6.6% fewer cycles; VIEW_SOURCE in check.py (a local holding a field the batch sets, a set from the same column in the order that overwrites what it reads, a set widening the column under a view), which differs and trips ASan's memcpy overlap when the copies are left out; seeds 1 2 3 5 23 (default and PURE_SELECT=all), the fixed sources (also sanitized) and the unit tests pass --- tests/check.py | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) (limited to 'tests') diff --git a/tests/check.py b/tests/check.py index 2314c36..1d98f05 100644 --- a/tests/check.py +++ b/tests/check.py @@ -1227,6 +1227,53 @@ on go { """ +# Columns read in place (VIEW_SOURCE, docs/design/025's stage 4): a local +# holding a row's field while the batch sets that field (its last value +# written back after the sets), a set whose value is the same column three +# rows over in the order that overwrites what it reads, and a set that widens +# the column to eight bytes while a local holds a view of it. +VIEW_SOURCE = """record Cell { + at = 0 + v = 0 +} +state last = 0 +state back = 0 +state wide = 0 +state sum = 0 +input go = message { + n: u32 + q: u32 +} +on go { + let t: list of Cell by at + for i in 0 .. go.n { + t.add(Cell { at: i, v: i * 3 }) + } + let a = 0 + for i in 0 .. go.n - 3 { + a = t[i].v + t[i].v = t[i + 3].v + 1 + } + last = a + for k in 0 .. go.n - 3 { + let i = go.n - 1 - k + t[i].v = t[i - 3].v + } + back = t[go.n - 1].v + t[go.n - 2].v * 1000 + let w = 0 + for i in 0 .. go.n - 3 { + w = t[i].v + t[i].v = t[i + 3].v + go.q + 0.5 + } + wide = w + let s = 0 + for c in t { + s = s + c.v + } + sum = s +} +""" + # Reductions that start with no lanes (REDUCE_SOURCE, docs/design/025): the # same e in every lane (a count, a uniform max and min, a fraction, a sum # past 2^53 one a lane), a count in a nested loop of the same rounds in @@ -1711,6 +1758,19 @@ def module_assumptions(aup, pure, work): assert outputs[name] == outputs['batches'], ('reduce', name, next((a, b) for a, b in zip(outputs[name].splitlines(), outputs['batches'].splitlines()) if a != b)) faults = [json.loads(line)['fault'] for line in outputs['batches'].splitlines() if line.startswith('{"states"')] assert 'none' in faults and 'work' in faults, faults + source, program = work / 'view.aup', work / 'view.pmod' # columns read in place, against the rounds one by one + source.write_text(VIEW_SOURCE) + compile_module(aup, source, program) + given = ''.join(f'message go {struct.pack("