From 10a50dd20abe8542d6ed6487d2c46d964af59c75 Mon Sep 17 00:00:00 2001 From: eunhhu Date: Mon, 5 Oct 2026 22:53:09 +0100 Subject: Batch executor stage 1 (024): a count's loop whose block has batch forms (lane forms, locals set before read in every round, ifs, numbers set in items) runs, in the executor, up to 1024 rounds at a time: values uniform, affine or lanes (numbers, or whole numbers in four bytes), branches as masks, cells read by affine rows as strided columns, sets kept to the batch's end and made only when no round reads an earlier round's; a fault, a form it lacks or such a read gives the rounds back to the executor one by one, work counted as written. Planned at load (PURE_BATCH=0: none); the executor of a module without such loops is the same code (run aligned to 64: as many instructions and cycles), with one its own copy. knapsack with PURE_JIT=0: 1,056 to 13.7 ms. module_tier compares batches with the executor alone and makes loops of rounds apart; BATCH_SOURCE: widened columns, -0, a fault mid-batch, rounds reading the last's sets --- tests/check.py | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 86 insertions(+), 7 deletions(-) (limited to 'tests/check.py') diff --git a/tests/check.py b/tests/check.py index 5ed8e8b..f330bae 100644 --- a/tests/check.py +++ b/tests/check.py @@ -1173,6 +1173,52 @@ on go { } """ +# Loops a batch runs (Pure docs/design/024) where it must give its rounds +# back or change a list's form (BATCH_SOURCE): cells past a byte and past +# four, a fraction and -0 set in the middle of a batch (the columns widened), +# 0 divided by at round q (a fault halfway through a batch: the executor's, +# at its round), each round reading the last one's set (not apart: run one +# by one), keys going down with an if and an else, two sets of one field. +BATCH_SOURCE = """record Cell { + at = 0 + v = 0 + w = 0 +} +state out = 0 +state low = 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 }) + } + for k in 0 .. go.n { + t[k].v = k * k * 1000 + t[k].w = k * (0 - 1) + } + for k in 0 .. go.n { + if k == go.q { t[k].v = 0.25 } else { t[k].w = t[k].w + 1 } + } + for k in 1 .. go.n { + t[k].v = t[k - 1].v + 1 + } + for k in 0 .. go.n { + let x = t[go.n - 1 - k].v + if x > 5000 { t[go.n - 1 - k].w = x - 5000 } else { t[go.n - 1 - k].w = 7 } + t[go.n - 1 - k].v = x + 1 + } + for k in 0 .. go.n { + t[k].w = 1000 / (k - go.q) + } + out = t[go.n - 1].v + t[0].w + low = t[floor(go.n / 2)].w +} +""" + + def module_assumptions(aup, pure, work): """The compiled code's integers (Pure docs/design/022) where they stop holding: a loop whose columns hold small whole numbers until, halfway, @@ -1211,6 +1257,19 @@ def module_assumptions(aup, pure, work): capture_output=True, text=True, timeout=120, env=dict(os.environ, PURE_JIT=jit)).stdout for jit in ('all', '0')} assert outputs['all'] == outputs['0'], (name, next((a, b) for a, b in zip(outputs['all'].splitlines(), outputs['0'].splitlines()) if a != b)) + source, program = work / 'batch.aup', work / 'batch.pmod' # batches against the executor's rounds one by one + source.write_text(BATCH_SOURCE) + compile_module(aup, source, program) + given = ''.join(f'message go {struct.pack("