From 4cb98b7beb83278e33a5577b9e83239eca403187 Mon Sep 17 00:00:00 2001 From: eunhhu Date: Tue, 6 Oct 2026 11:09:18 +0100 Subject: Batch: a count's loop whose block begins if slot >= L.count { break } (L only grown in it) batches to L's count as each batch opens (PLAN_GUARD; fewer than LEAST rounds left there: the executor's, then batches again); a walk in a batch's block (its slice per lane, no where's range) runs each lane's items, its work counted as each opens: together round by round (BREAK as a nested loop's), or spread into lanes in the rounds' order a chunk of up to 1024 at a time when its items' rounds may run apart (PLAN_SPREAD: no break, the locals it sets reductions or its items' own: an outer lane's value read by each item's outer lane, a reduction added into its outer lane's in the items' order, an own local left as the last item that set it); rows in four bytes read and checked by loops of their own. A frontier walk of the suite's graph (each node's edges' to summed) PURE_JIT=0 55.2 to 10.4 ms (the compiled code 6.24). module_tier makes guarded loops with a walk in each (seeds 1, 2, 3, 5, 23 alike: 8,819 spread and 7,651 together in seed 23's); FRONT_SOURCE --- tests/check.py | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 96 insertions(+), 1 deletion(-) (limited to 'tests/check.py') diff --git a/tests/check.py b/tests/check.py index 1fe7079..731c5f8 100644 --- a/tests/check.py +++ b/tests/check.py @@ -1338,6 +1338,58 @@ on go { """ +# Walks in a batch's rounds (FRONT_SOURCE): a count's loop to a list's +# count (if i >= L.count { break }, past it as the loop goes on), each +# round walking its slice of a keyed list (slices of every length, empty +# too) with sums of fractions (their order tells), the most, an item's own +# local and the round's value read in it (its items spread apart into +# lanes); a walk that breaks out (its items together, round by round); a +# division by 0 in some round's item; under work budgets that run out +# within a walk. +FRONT_SOURCE = """record Cell { + at = 0 + v = 0 +} +state total = 0 +state most = 0 +state last = 0 +state broke = 0 +input go = message { + n: u32 + q: u32 +} +on go { + let g: list of Cell by at + let f: list of Cell + for i in 0 .. go.n { + g.add(Cell { at: i * 3, v: i * 0.25 + 1 }) + f.append(Cell { at: i, v: floor(i / 7) }) + } + let s = 0 + let m = 0 + let k = 0 + let z = 0 + for i in 0 .. go.n * 2 + 5 { + if i >= f.count { break } + let w = f[f.first + i].v + for c in g[i * 3 - w .. i * 3 + w * 2] { + let o = c.v * 0.1 + w + s = s + o + m = max(m, c.v - i) + z = z + 1 / (c.at - go.q) + } + for c in g[i .. i + 9] { + if c.v > 3 + w { break } + k = k + c.v + } + } + total = s + most = m + last = k + broke = z +} +""" + # Items a batch appends at once (APPEND_SOURCE): keys there already, met # at round q of a DENSE list and at round p of a HASHED one (the # executor's fault at that round); keys past what a DENSE list holds from @@ -1448,6 +1500,19 @@ def module_assumptions(aup, pure, work): assert outputs[name] == outputs['batches'], ('recur', 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 'non_finite' in faults and 'memory' in faults, faults + source, program = work / 'front.aup', work / 'front.pmod' # walks in a batch's rounds, against the rounds one by one + source.write_text(FRONT_SOURCE) + compile_module(aup, source, program) + given = ''.join(f'message go {struct.pack("= {rng.choice(["f", "g", "h", "e"])}.count {{ break }}') + lines.append(f'{pad} let {w} = {number(2, loops + [name])}') + walked = rng.choice(['f', 'g', f'g[{name} .. {name} + {rng.choice(["3", w, "go.q"])}]', f'g[{w} .. {name} * 2 + 5]', + f'g[{name} .. {name}]', f'h[5000000 + {name} .. 5000100]', f'f[{name} .. 9]']) + inner = loops + [name, w, 'c'] + lines.append(f'{pad} for c in {walked} {{') + own = False + for _ in range(rng.randint(1, 3)): + pick = rng.random() + if pick < 0.3: + lines.append(f'{pad} ra = ra + {rng.choice(["c.v", "c.at", w, number(2, inner)])}') + elif pick < 0.45: + lines.append(f'{pad} rb = {rng.choice(["max", "min"])}(rb, {rng.choice(["c.v", w, number(2, inner)])})') + elif pick < 0.65 and not own: # the item's own local + own = True + lines.append(f'{pad} let o{name} = {number(2, inner)}') + lines.append(f'{pad} rc = rc + o{name}') + elif pick < 0.85: + lines.append(f'{pad} if {cond(1, inner)} {{ ra = ra + {rng.choice(["c.v", w])} }}') + else: + lines.append(f'{pad} if {cond(1, inner)} {{ break }}') + lines.append(f'{pad} }}') + lines.append(f'{pad} rc = rc + {w}') + lines.append(f'{pad}}}') elif kind == 'walk' and 'c' not in loops: lines.append(f'{pad}for c in f {{') lines += statements(depth + 1, loops + ['c'], indent + 1, True) -- cgit v1.2.3