From 390169f69dc61ad12f9acb1edc8f1ccee359c696 Mon Sep 17 00:00:00 2001 From: eunhhu Date: Mon, 5 Oct 2026 23:13:47 +0100 Subject: Batch executor stage 2 (024): a loop in the batch's block runs its rounds for every lane together (round t for the lanes with more than t rounds that did not break out; BREAK leaves it lane by lane; its slot as each round sets it), and x = x op e (op +, min, max; x read no other way) is a reduction: each lane's own from op's identity (-0 a sum's), folded in the rounds' order at the batch's end (a sum's lanes of several whole numbers only, below 2^53); nested rounds' work counted for each lane and checked before anything changes; lanes and masks no holder keeps freed between nested rounds. Planned at load: a local read before set in its loop's scope, or not a reduction's, keeps the loop round by round. PURE_JIT=0: roots 130.5 to 16.8 ms, matmul 914.7 to 68.2. module_tier makes nested loops with breaks and reductions (seeds 1, 2, 3, 23: 549 programs alike); NESTED_SOURCE --- tests/check.py | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 111 insertions(+), 5 deletions(-) (limited to 'tests') diff --git a/tests/check.py b/tests/check.py index f330bae..ff04e09 100644 --- a/tests/check.py +++ b/tests/check.py @@ -1219,6 +1219,74 @@ on go { """ +# Nested loops a batch runs together, and reductions (NESTED_SOURCE): Newton +# steps breaking out lane by lane, a sum of fractions one a round, a nested +# loop of 0 to 6 rounds a lane whose division by 0 is a fault in some +# lane's round (q < 4), max and min, a sum of fractions several a lane (the +# batch gives its rounds back), -0 summed, a grid's sums. +NESTED_SOURCE = """state total = 0 +state steps = 0 +state most = 0 +state least = 0 +state frac = 0 +state zero = 0 +state grid = 0 +input go = message { + n: u32 + q: u32 +} +on go { + let sum = 0 + let count = 0 + for i in 1 .. go.n + 1 { + let r = i + for s in 0 .. 64 { + let next = (r + i / r) / 2 + if next >= r { break } + r = next + count = count + 1 + } + sum = sum + r + } + let high = 0 + let low = 0 + for i in 0 .. go.n { + let w = 0 + for k in 0 .. i - floor(i / 7) * 7 { + w = w + 1000 / (k + go.q - 3) + } + high = max(high, w) + low = min(low, 0 - w) + } + let f = 0 + for i in 0 .. go.n { + for k in 0 .. 3 { + f = f + 0.1 + } + } + let z = 0 * (0 - 1) + for i in 0 .. go.n { + z = z + 0 * (0 - 1) + } + let g = 0 + for j in 0 .. go.n { + let c = 0 + for k in 0 .. 20 { + c = c + (j * 7 + k) * (k + 1) + } + g = g + c + } + total = sum + steps = count + most = high + least = low + frac = f + zero = z + grid = g +} +""" + + 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, @@ -1270,6 +1338,19 @@ def module_assumptions(aup, pure, work): assert outputs[name] == outputs['batches'], ('batch', 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 'divide' in faults and 'none' in faults and 'work' in faults, faults + source, program = work / 'nested.aup', work / 'nested.pmod' # nested loops together and reductions, against the rounds one by one + source.write_text(NESTED_SOURCE) + compile_module(aup, source, program) + given = ''.join(f'message go {struct.pack("