aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authoreunhhu <[email protected]>2026-10-19 06:18:49 +0100
committereunhhu <[email protected]>2026-10-19 06:18:49 +0100
commit6215b1177e377b512aaa1296faa6311f809135f2 (patch)
treed2be13b3e5d4cb0b7150b0a6d186fc313842de18 /tests
parent8071832bc7857634f66c94592b27b188c882ea54 (diff)
downloadpure-6215b1177e377b512aaa1296faa6311f809135f2.tar.gz
pure-6215b1177e377b512aaa1296faa6311f809135f2.zip
140's 8, box layout, written in aup with no new opcode (aup's examples/layout.aup: a subset of CSS Flexbox 1 written down first, one line, row or column, padding, gap, six justify-content, four align-items, grow and shrink with 9.7's loop, cross sizes stretched, nothing sized by content): 2,000 random trees (29,388 nodes; 7,659 items frozen at their padding by the loop) are Taffy 0.15's within 0.01 (layout_taffy, built by cargo; the worst 8.3e-5) and layout.py's bit for bit on the three paths, the paths the same; the single-pass subset first tried refused 66% of trees, so the loop came in; Taffy given min sizes equal to the padding (given 0 it floors at 0 while resolving lengths, where 9.7 floors the content box), the reference adding from the left (sum compensates since Python 3.12); module_specs in make check: 100 trees (tests/specs/layout); bars: 116 lines against Python's 54, 4,754 ns a node, Taffy's 644 (7.4x), pure Python 5,396 (Pure 1.14x faster), 1,494 instructions a node (9.7's loop 44%); four frictions; aup's rows read by position no longer copy (99,067 ns a node before); the suite table's row 8; CHECKPOINT's direction row
Diffstat (limited to 'tests')
-rw-r--r--tests/check.py25
-rw-r--r--tests/specs/layout/README.md7
-rw-r--r--tests/specs/layout/trees.binbin0 -> 218992 bytes
3 files changed, 31 insertions, 1 deletions
diff --git a/tests/check.py b/tests/check.py
index 5574b80..dd64e03 100644
--- a/tests/check.py
+++ b/tests/check.py
@@ -1738,7 +1738,9 @@ def module_specs(aup, pure, work):
at a time, cut anywhere, to the same requests; line breaking (UAX #14) by its
examples/linebreak.aup on LineBreakTest.txt's lines (tests/specs/linebreak);
RFC 6298's retransmission timer by its examples/rto.aup on a scenario's
- events (tests/specs/rto), the model's state after each."""
+ events (tests/specs/rto), the model's state after each; box layout (a
+ subset of CSS Flexbox 1) by its examples/layout.aup on trees
+ (tests/specs/layout), each box bit for bit."""
import hashlib
import os
import random
@@ -1988,6 +1990,27 @@ def module_specs(aup, pure, work):
len(s['retransmits'])] == want, ('rto', period, want)
events += len(out)
runs['rto'] = {'scenarios': 2, 'events': events}
+ # Box layout (a subset of CSS Flexbox 1, its examples/layout.aup): trees as layout.py lays them out (tests/specs/layout,
+ # Taffy's within 0.01), a tree a message of its nodes in preorder, its boxes bit for bit on the three paths.
+ program = work / 'layout.pmod'
+ compile_module(aup, EXAMPLES / 'layout.aup', program)
+ given, trees = (pure / 'tests/specs/layout/trees.bin').read_bytes(), []
+ while given:
+ n = struct.unpack_from('<I', given)[0]
+ trees.append((given[4:4 + 112 * n], [list(struct.unpack_from('<4d', given, 4 + 112 * n + 32 * k)) for k in range(n)]))
+ given = given[4 + 144 * n:]
+ given = ''.join(f'message tree {rows.hex()}\n' for rows, _ in trees)
+ shown = {name: subprocess.run([str(pure / 'build/pure-run'), str(program)], input=given, capture_output=True, text=True,
+ timeout=120, env=dict(os.environ, **env)).stdout
+ for name, env in (('batches', {'PURE_JIT': '0'}), ('rounds', {'PURE_JIT': '0', 'PURE_BATCH': '0'}), ('all', {'PURE_JIT': 'all'}))}
+ for name in ('rounds', 'all'):
+ assert shown[name] == shown['batches'], ('layout', name)
+ out = shown['batches'].splitlines()
+ assert len(out) == len(trees), ('layout', len(out))
+ for (_, want), line in zip(trees, out):
+ state = json.loads(line)
+ assert state['fault'] == 'none' and [[b['x'], b['y'], b['w'], b['h']] for b in state['states']['boxes']] == want, want
+ runs['layout'] = {'trees': len(trees), 'nodes': sum(len(w) for _, w in trees)}
return runs
diff --git a/tests/specs/layout/README.md b/tests/specs/layout/README.md
new file mode 100644
index 0000000..3341c4e
--- /dev/null
+++ b/tests/specs/layout/README.md
@@ -0,0 +1,7 @@
+# Box layout (a subset of CSS Flexbox 1): 100 trees
+
+`trees.bin` holds the first 100 trees `research/experiments/044-specs/layout_check.py` draws, each a u32 count of its
+nodes, their rows in preorder (14 binary64s: parent, column, w, h, grow, shrink, basis, left, right, top, bottom, gap,
+justify, align), then their boxes (x, y, w, h, each relative to its parent's), as `layout.py` works them out; Taffy
+0.15's are the same within 0.01. `tests/check.py`'s `module_specs` gives each tree to aup's `examples/layout.aup` as a
+message, on Pure's three paths: its boxes must be these, bit for bit.
diff --git a/tests/specs/layout/trees.bin b/tests/specs/layout/trees.bin
new file mode 100644
index 0000000..387caff
--- /dev/null
+++ b/tests/specs/layout/trees.bin
Binary files differ