c-tier: emit-circuit-to-ops-bin-stream — streaming-emit primitive

Ports lumbda.py _emit_circuit_to_ops_bin_stream to C tier. Walks a
Scheme registers + ops list, writes each 56-byte QECCOPS1 op record
straight to disk via fopen/fwrite, then seeks back to patch the n_ops
header at the tail. O(1) host memory regardless of n_ops.

Cross-tier byte-identity verified:
  * 500-op mixed-tag synthetic circuit on host: Python ↔ C identical
  * real-point-add n+1=5 (p=11, 94,214 ops, 5.0 MB) inside VM
  * real-point-add n+1=9 (p=251, 674,872 ops, 36 MB) inside VM
  sha256 matches every width.

Speedup on equal Scheme source (build + emit combined):
  * n+1=5:  Python 56.8 s → C 1.1 s  (52×)
  * n+1=9:  Python 365 s  → C 8.4 s  (43×)
Combined ratio exceeds the prior 11-16× C-tier envelope because the
build phase (Phase B mod-arith construction) also accelerates on C;
emit-only ratio is ~3-9× and grows with op count.

C test suite: 85 → 88 passing (emit-stream-basic, alloc-free, empty).
Shared functional suite: 205/205 still passing on both tiers.

Implementation notes:
  * pack_op_record packs u32 kind + u32 pad + 6× u64 LE, matching
    op-specs->bytes byte layout exactly.
  * Layout hashtable Symbol → fixnum base, mirroring walk-circuit-ops.
  * NO_SLOT sentinel: 0xFFFFFFFFFFFFFFFF written directly to u64 slots
    that the Scheme side did not populate.
  * libc's default fwrite buffer (~4 KB) handles batching at ~73 ops
    per write — same throughput class as Python tier's 8 KiB list batch.
This commit is contained in:
russell@unturf.com 2026-06-07 11:36:46 -04:00
parent 661f9a01ec
commit f398902cc4
No known key found for this signature in database
2 changed files with 474 additions and 0 deletions

View file

@ -1669,6 +1669,258 @@ static Value bi_count_lumbda_ops(Value *a, int n, Env *e) {
return make_vector_from(items, 3);
}
/* emit-circuit-to-ops-bin-stream — streaming-emit walker that writes
* each 56-byte QECCOPS1 op record directly to a file as it is produced.
* O(1) host memory regardless of n_ops. C-tier port of lumbda.py
* _emit_circuit_to_ops_bin_stream. Byte-identical output across tiers.
*
* Calling shape (matches Python tier):
* (emit-circuit-to-ops-bin-stream out-path registers ops)
* out-path string destination file
* registers list of (name width) pairs (declared registers)
* ops list of (tag ) op records (lumbda ops, same shape as
* walk-circuit-ops input)
* returns n_ops written (fixnum)
*
* File format (QECCOPS1):
* magic 8B "QECCOPS1"
* n_ops 8B u64 LE (placeholder zero, patched at tail via fseek)
* body n_ops × 56B (matches op-specs->bytes layout exactly)
*
* Per-op record layout (56 B little-endian):
* u32 kind | u32 pad=0 | u64 q2 | u64 q1 | u64 qt | u64 ct | u64 cc | u64 rt
*
* Kind dispatch & layout mirror bi_walk_circuit_ops (above) single
* source of truth. NO_SLOT representation: 0xFFFFFFFFFFFFFFFF, written
* directly into u64 slots that the Scheme side did not populate.
*
* Buffering: libc's default fwrite buffer (~4 KB) plus the 56-byte
* records means each disk write covers ~73 ops same throughput class
* as the Python tier's 8 KiB manual batch. fflush + fclose at the tail
* commit everything before the function returns.
*
* Layout map: ULHashTable Symbol fixnum base (same as walk-circuit-ops).
* Returning the symbol's qubit base; we never need width after the
* Register/Append boilerplate is emitted, so we store just the base. */
static void pack_op_record(char *buf, uint32_t kind,
uint64_t q2, uint64_t q1, uint64_t qt,
uint64_t ct, uint64_t cc, uint64_t rt) {
/* u32 kind */
buf[0] = (char)(kind & 0xFF);
buf[1] = (char)((kind >> 8) & 0xFF);
buf[2] = (char)((kind >> 16) & 0xFF);
buf[3] = (char)((kind >> 24) & 0xFF);
/* u32 pad */
buf[4] = 0; buf[5] = 0; buf[6] = 0; buf[7] = 0;
/* 6× u64 LE */
uint64_t u[6] = { q2, q1, qt, ct, cc, rt };
for (int i = 0; i < 6; i++) {
size_t off = 8 + i * 8;
uint64_t x = u[i];
buf[off + 0] = (char)(x & 0xFF);
buf[off + 1] = (char)((x >> 8) & 0xFF);
buf[off + 2] = (char)((x >> 16) & 0xFF);
buf[off + 3] = (char)((x >> 24) & 0xFF);
buf[off + 4] = (char)((x >> 32) & 0xFF);
buf[off + 5] = (char)((x >> 40) & 0xFF);
buf[off + 6] = (char)((x >> 48) & 0xFF);
buf[off + 7] = (char)((x >> 56) & 0xFF);
}
}
/* Write one op record to f, bumping count. Returns 0 on success, -1 on
* fwrite failure (caller closes & errors). */
#define NO_SLOT_U64 0xFFFFFFFFFFFFFFFFULL
static int emit_one(FILE *f, uint64_t *count,
uint32_t kind,
uint64_t q2, uint64_t q1, uint64_t qt,
uint64_t ct, uint64_t cc, uint64_t rt) {
char rec[56];
pack_op_record(rec, kind, q2, q1, qt, ct, cc, rt);
if (fwrite(rec, 1, 56, f) != 56) return -1;
(*count)++;
return 0;
}
/* Emit Register + width × AppendToRegister boilerplate.
* Reg-id = base = next_q at time of emit (matches Python tier semantics:
* reg_id = base in _emit_circuit_to_ops_bin_stream::emit_register).
* Updates layout (name base) and returns new next_q.
* Returns -1 on fwrite failure, 0 on success. */
static int emit_register_stream(FILE *f, uint64_t *count,
ULHashTable *layout,
Value name, int64_t width,
int64_t *next_q) {
int64_t base = *next_q;
uint64_t reg_id = (uint64_t)base;
ht_set(layout, name, VAL_INT(base));
/* Register record. */
if (emit_one(f, count, 1,
NO_SLOT_U64, NO_SLOT_U64, NO_SLOT_U64,
NO_SLOT_U64, NO_SLOT_U64, reg_id) < 0) return -1;
/* width × AppendToRegister. */
for (int64_t i = 0; i < width; i++) {
if (emit_one(f, count, 2,
NO_SLOT_U64, NO_SLOT_U64,
(uint64_t)(base + i),
NO_SLOT_U64, NO_SLOT_U64, reg_id) < 0) return -1;
}
*next_q += width;
return 0;
}
static Value bi_emit_circuit_to_ops_bin_stream(Value *a, int n, Env *e) {
(void)e; CHECK_ARITY("emit-circuit-to-ops-bin-stream", 3);
check_string(a[0]);
walk_syms_init();
const char *out_path = AS_STRING(a[0])->data;
Value registers_lst = a[1];
Value ops_lst = a[2];
FILE *f = fopen(out_path, "wb");
if (!f) lisp_error("emit-circuit-to-ops-bin-stream: cannot open %s", out_path);
/* Header: magic + zero placeholder for n_ops (patched at tail). */
if (fwrite("QECCOPS1", 1, 8, f) != 8) {
fclose(f);
lisp_error("emit-circuit-to-ops-bin-stream: write magic failed");
}
char zero8[8] = {0,0,0,0,0,0,0,0};
if (fwrite(zero8, 1, 8, f) != 8) {
fclose(f);
lisp_error("emit-circuit-to-ops-bin-stream: write header n_ops placeholder failed");
}
Value layout_v = make_hashtable();
ULHashTable *layout = AS_HASHTABLE(layout_v);
int64_t next_q = 0;
uint64_t count = 0;
int err = 0;
/* Declared registers first (boilerplate before ops). */
while (IS_PAIR(registers_lst)) {
Value rec = CAR(registers_lst);
Value name = CAR(rec);
int64_t width = as_int(CADR(rec));
if (emit_register_stream(f, &count, layout, name, width, &next_q) < 0) {
err = 1; break;
}
registers_lst = CDR(registers_lst);
}
/* Walk ops. */
while (!err && IS_PAIR(ops_lst)) {
Value op = CAR(ops_lst);
Value tag = CAR(op);
Value rest = CDR(op);
if (tag == g_sym_ccx) {
Value c1 = CAR(rest);
Value c2 = CAR(CDR(rest));
Value tgt = CAR(CDR(CDR(rest)));
int64_t q1 = layout_base(layout, CAR(c1)) + as_int(CADR(c1));
int64_t q2 = layout_base(layout, CAR(c2)) + as_int(CADR(c2));
int64_t qt = layout_base(layout, CAR(tgt)) + as_int(CADR(tgt));
if (emit_one(f, &count, 13,
(uint64_t)q2, (uint64_t)q1, (uint64_t)qt,
NO_SLOT_U64, NO_SLOT_U64, NO_SLOT_U64) < 0) err = 1;
} else if (tag == g_sym_cx) {
Value c1 = CAR(rest);
Value tgt = CAR(CDR(rest));
int64_t q1 = layout_base(layout, CAR(c1)) + as_int(CADR(c1));
int64_t qt = layout_base(layout, CAR(tgt)) + as_int(CADR(tgt));
if (emit_one(f, &count, 8,
NO_SLOT_U64, (uint64_t)q1, (uint64_t)qt,
NO_SLOT_U64, NO_SLOT_U64, NO_SLOT_U64) < 0) err = 1;
} else if (tag == g_sym_x) {
Value tgt = CAR(rest);
int64_t qt = layout_base(layout, CAR(tgt)) + as_int(CADR(tgt));
if (emit_one(f, &count, 6,
NO_SLOT_U64, NO_SLOT_U64, (uint64_t)qt,
NO_SLOT_U64, NO_SLOT_U64, NO_SLOT_U64) < 0) err = 1;
} else if (tag == g_sym_alloc) {
Value name = CAR(rest);
int64_t width = as_int(CADR(rest));
if (emit_register_stream(f, &count, layout, name, width, &next_q) < 0) err = 1;
} else if (tag == g_sym_free) {
Value name = CAR(rest);
ht_delete(layout, name);
} else if (tag == g_sym_z) {
Value tgt = CAR(rest);
int64_t qt = layout_base(layout, CAR(tgt)) + as_int(CADR(tgt));
if (emit_one(f, &count, 7,
NO_SLOT_U64, NO_SLOT_U64, (uint64_t)qt,
NO_SLOT_U64, NO_SLOT_U64, NO_SLOT_U64) < 0) err = 1;
} else if (tag == g_sym_cz) {
Value c1 = CAR(rest);
Value tgt = CAR(CDR(rest));
int64_t q1 = layout_base(layout, CAR(c1)) + as_int(CADR(c1));
int64_t qt = layout_base(layout, CAR(tgt)) + as_int(CADR(tgt));
if (emit_one(f, &count, 9,
NO_SLOT_U64, (uint64_t)q1, (uint64_t)qt,
NO_SLOT_U64, NO_SLOT_U64, NO_SLOT_U64) < 0) err = 1;
} else if (tag == g_sym_swap) {
Value aa = CAR(rest);
Value bb = CAR(CDR(rest));
int64_t q1 = layout_base(layout, CAR(aa)) + as_int(CADR(aa));
int64_t qt = layout_base(layout, CAR(bb)) + as_int(CADR(bb));
if (emit_one(f, &count, 10,
NO_SLOT_U64, (uint64_t)q1, (uint64_t)qt,
NO_SLOT_U64, NO_SLOT_U64, NO_SLOT_U64) < 0) err = 1;
} else if (tag == g_sym_ccz) {
Value c1 = CAR(rest);
Value c2 = CAR(CDR(rest));
Value tgt = CAR(CDR(CDR(rest)));
int64_t q1 = layout_base(layout, CAR(c1)) + as_int(CADR(c1));
int64_t q2 = layout_base(layout, CAR(c2)) + as_int(CADR(c2));
int64_t qt = layout_base(layout, CAR(tgt)) + as_int(CADR(tgt));
if (emit_one(f, &count, 14,
(uint64_t)q2, (uint64_t)q1, (uint64_t)qt,
NO_SLOT_U64, NO_SLOT_U64, NO_SLOT_U64) < 0) err = 1;
} else {
fclose(f);
lisp_error("emit-circuit-to-ops-bin-stream: unknown op tag");
}
ops_lst = CDR(ops_lst);
}
if (err) {
fclose(f);
lisp_error("emit-circuit-to-ops-bin-stream: fwrite failed");
}
/* Patch n_ops header. u64 LE at offset 8. */
if (fflush(f) != 0) {
fclose(f);
lisp_error("emit-circuit-to-ops-bin-stream: fflush failed");
}
if (fseek(f, 8, SEEK_SET) != 0) {
fclose(f);
lisp_error("emit-circuit-to-ops-bin-stream: fseek failed");
}
char nbuf[8];
uint64_t nu = count;
nbuf[0] = (char)(nu & 0xFF);
nbuf[1] = (char)((nu >> 8) & 0xFF);
nbuf[2] = (char)((nu >> 16) & 0xFF);
nbuf[3] = (char)((nu >> 24) & 0xFF);
nbuf[4] = (char)((nu >> 32) & 0xFF);
nbuf[5] = (char)((nu >> 40) & 0xFF);
nbuf[6] = (char)((nu >> 48) & 0xFF);
nbuf[7] = (char)((nu >> 56) & 0xFF);
if (fwrite(nbuf, 1, 8, f) != 8) {
fclose(f);
lisp_error("emit-circuit-to-ops-bin-stream: header patch write failed");
}
if (fclose(f) != 0) {
lisp_error("emit-circuit-to-ops-bin-stream: fclose failed");
}
return VAL_INT((int64_t)count);
}
#undef NO_SLOT_U64
/* heap-snapshot / heap-restore: asm-only arena primitives. The asm impl
* has no GC; these let a server rewind its bump allocator between
* requests. Python + C have real GCs no-ops here so portable .lsp
@ -2359,6 +2611,7 @@ Env *make_global_env(void) {
DEF("walk-circuit-ops", bi_walk_circuit_ops);
DEF("op-specs->bytes", bi_op_specs_to_bytes);
DEF("count-lumbda-ops", bi_count_lumbda_ops);
DEF("emit-circuit-to-ops-bin-stream", bi_emit_circuit_to_ops_bin_stream);
DEF("heap-snapshot", bi_heap_snapshot);
DEF("heap-restore", bi_heap_restore);
DEF("current-time-ms", bi_current_time_ms);

221
c/test.c
View file

@ -914,6 +914,222 @@ TEST(portal_checkpoint_builtin) {
unlink("/tmp/test_checkpoint.json");
}
/* ═══════════════════════════════════════════════════════════════════════════
* emit-circuit-to-ops-bin-stream streaming-emit primitive
*
* Tests build a small register + ops list via the Scheme reader, call the
* primitive against a temp file, then read the bytes back & compare byte-
* for-byte against a hand-rolled QECCOPS1 layout. Catches both kind/slot
* packing & header-patch path. Cross-tier byte-identity with Python lives
* outside the C unit-test harness (foxhop.net's vm-runner.sh envelope).
* */
/* Hand-roll a 56-byte op record matching pack_op_record / op-specs->bytes. */
static void pack_rec_expected(unsigned char *buf, uint32_t kind,
uint64_t q2, uint64_t q1, uint64_t qt,
uint64_t ct, uint64_t cc, uint64_t rt) {
buf[0] = (unsigned char)(kind & 0xFF);
buf[1] = (unsigned char)((kind >> 8) & 0xFF);
buf[2] = (unsigned char)((kind >> 16) & 0xFF);
buf[3] = (unsigned char)((kind >> 24) & 0xFF);
buf[4] = 0; buf[5] = 0; buf[6] = 0; buf[7] = 0;
uint64_t slots[6] = { q2, q1, qt, ct, cc, rt };
for (int i = 0; i < 6; i++) {
size_t off = 8 + i * 8;
uint64_t x = slots[i];
buf[off + 0] = (unsigned char)(x & 0xFF);
buf[off + 1] = (unsigned char)((x >> 8) & 0xFF);
buf[off + 2] = (unsigned char)((x >> 16) & 0xFF);
buf[off + 3] = (unsigned char)((x >> 24) & 0xFF);
buf[off + 4] = (unsigned char)((x >> 32) & 0xFF);
buf[off + 5] = (unsigned char)((x >> 40) & 0xFF);
buf[off + 6] = (unsigned char)((x >> 48) & 0xFF);
buf[off + 7] = (unsigned char)((x >> 56) & 0xFF);
}
}
#define NO_SLOT_TEST 0xFFFFFFFFFFFFFFFFULL
TEST(emit_stream_basic) {
/* Small circuit: one declared register 'a' width 3, then x/cx/ccx ops.
* Run primitive into temp file. Compare bytes against expected layout.
*
* Expected ops sequence:
* Register reg-id=0
* Append qt=0 reg=0
* Append qt=1 reg=0
* Append qt=2 reg=0
* X qt=1
* CX q1=0 qt=2
* CCX q2=2 q1=0 qt=1
* Total: 7 ops. */
const char *path = "/tmp/test_emit_stream_basic.bin";
unlink(path);
char src[1024];
snprintf(src, sizeof(src),
"(emit-circuit-to-ops-bin-stream \"%s\" '((a 3)) "
" '((x (a 1)) (cx (a 0) (a 2)) (ccx (a 0) (a 2) (a 1))))",
path);
Value r = run(src);
ASSERT(IS_INT(r), "primitive must return fixnum");
/* 1 Register + 3 Append + 1 X + 1 CX + 1 CCX = 7. */
ASSERT_EQ_INT(as_int(r), 7);
FILE *f = fopen(path, "rb");
ASSERT(f != NULL, "output file must exist");
fseek(f, 0, SEEK_END);
long sz = ftell(f);
fseek(f, 0, SEEK_SET);
/* 16-byte header + 7×56 = 408. */
ASSERT_EQ_INT(sz, 16 + 7 * 56);
unsigned char *got = (unsigned char *)ul_malloc(sz);
ASSERT(fread(got, 1, sz, f) == (size_t)sz, "read full file");
fclose(f);
/* Build expected bytes. */
unsigned char exp[16 + 7 * 56];
memcpy(exp, "QECCOPS1", 8);
/* n_ops = 7 LE. */
exp[8] = 7; exp[9] = 0; exp[10] = 0; exp[11] = 0;
exp[12] = 0; exp[13] = 0; exp[14] = 0; exp[15] = 0;
size_t off = 16;
/* kind 1 Register, reg-id=0. */
pack_rec_expected(exp + off, 1,
NO_SLOT_TEST, NO_SLOT_TEST, NO_SLOT_TEST,
NO_SLOT_TEST, NO_SLOT_TEST, 0); off += 56;
/* 3 × Append. */
for (int i = 0; i < 3; i++) {
pack_rec_expected(exp + off, 2,
NO_SLOT_TEST, NO_SLOT_TEST, (uint64_t)i,
NO_SLOT_TEST, NO_SLOT_TEST, 0); off += 56;
}
/* X qt=1. */
pack_rec_expected(exp + off, 6,
NO_SLOT_TEST, NO_SLOT_TEST, 1,
NO_SLOT_TEST, NO_SLOT_TEST, NO_SLOT_TEST); off += 56;
/* CX q1=0 qt=2. */
pack_rec_expected(exp + off, 8,
NO_SLOT_TEST, 0, 2,
NO_SLOT_TEST, NO_SLOT_TEST, NO_SLOT_TEST); off += 56;
/* CCX q2=2 q1=0 qt=1. */
pack_rec_expected(exp + off, 13,
2, 0, 1,
NO_SLOT_TEST, NO_SLOT_TEST, NO_SLOT_TEST); off += 56;
for (long i = 0; i < sz; i++) {
if (got[i] != exp[i]) {
ul_free(got);
unlink(path);
lisp_error("byte %ld differs: got 0x%02x, expected 0x%02x",
i, got[i], exp[i]);
}
}
ul_free(got);
unlink(path);
}
TEST(emit_stream_alloc_free) {
/* Exercise alloc & free op tags: declared register, then alloc ancilla,
* use it, free it, alloc again (reusing next-q monotonic). The C tier
* does NOT pool base monotonically grows. Mirrors Python behavior. */
const char *path = "/tmp/test_emit_stream_alloc_free.bin";
unlink(path);
char src[2048];
snprintf(src, sizeof(src),
"(emit-circuit-to-ops-bin-stream \"%s\" '((tx 2)) "
" '((alloc anc 2)"
" (cx (tx 0) (anc 1))"
" (free anc)"
" (alloc anc2 1)"
" (x (anc2 0))))",
path);
Value r = run(src);
ASSERT(IS_INT(r), "primitive must return fixnum");
/* tx: Register + 2 Append = 3
* alloc anc 2: Register + 2 Append = 3
* cx: 1
* free: 0 (no op emitted)
* alloc anc2 1: Register + 1 Append = 2
* x: 1
* Total: 10. */
ASSERT_EQ_INT(as_int(r), 10);
FILE *f = fopen(path, "rb");
ASSERT(f != NULL, "output file must exist");
fseek(f, 0, SEEK_END);
long sz = ftell(f);
fseek(f, 0, SEEK_SET);
ASSERT_EQ_INT(sz, 16 + 10 * 56);
unsigned char *got = (unsigned char *)ul_malloc(sz);
ASSERT(fread(got, 1, sz, f) == (size_t)sz, "read full file");
fclose(f);
/* Verify magic + n_ops header. */
ASSERT(memcmp(got, "QECCOPS1", 8) == 0, "magic mismatch");
uint64_t n_ops = (uint64_t)got[8]
| ((uint64_t)got[9] << 8)
| ((uint64_t)got[10] << 16)
| ((uint64_t)got[11] << 24)
| ((uint64_t)got[12] << 32)
| ((uint64_t)got[13] << 40)
| ((uint64_t)got[14] << 48)
| ((uint64_t)got[15] << 56);
ASSERT_EQ_INT((int64_t)n_ops, 10);
/* Verify cx record: qubit 0 = tx base, qubit 3 = anc base+1.
* tx base = 0 (next_q was 0). After tx: next_q = 2.
* alloc anc: base = 2. anc 1 = 3. After: next_q = 4.
* cx q1 = 0, qt = 3.
* Records:
* 0-2: tx Register, Append qt=0, Append qt=1 (reg=0)
* 3-5: anc Register reg=2, Append qt=2, Append qt=3 (reg=2)
* 6: cx q1=0 qt=3
* 7-8: anc2 Register reg=4, Append qt=4 (reg=4)
* 9: x qt=4
*/
/* Spot-check the cx record (record index 6, offset = 16 + 6*56 = 352). */
size_t cx_off = 16 + 6 * 56;
/* kind LE = 8. */
ASSERT_EQ_INT(got[cx_off], 8);
ASSERT_EQ_INT(got[cx_off + 1], 0);
/* q2 slot (offset +8) = NO_SLOT (all 0xFF). */
for (int i = 0; i < 8; i++) ASSERT_EQ_INT(got[cx_off + 8 + i], 0xFF);
/* q1 slot (offset +16) = 0. */
for (int i = 0; i < 8; i++) ASSERT_EQ_INT(got[cx_off + 16 + i], 0);
/* qt slot (offset +24) = 3. */
ASSERT_EQ_INT(got[cx_off + 24], 3);
for (int i = 1; i < 8; i++) ASSERT_EQ_INT(got[cx_off + 24 + i], 0);
ul_free(got);
unlink(path);
}
TEST(emit_stream_empty) {
/* No registers, no ops — should produce just header w/ n_ops=0. */
const char *path = "/tmp/test_emit_stream_empty.bin";
unlink(path);
char src[256];
snprintf(src, sizeof(src),
"(emit-circuit-to-ops-bin-stream \"%s\" '() '())", path);
Value r = run(src);
ASSERT(IS_INT(r), "primitive must return fixnum");
ASSERT_EQ_INT(as_int(r), 0);
FILE *f = fopen(path, "rb");
ASSERT(f != NULL, "output file must exist");
unsigned char hdr[16];
ASSERT(fread(hdr, 1, 16, f) == 16, "read 16-byte header");
/* EOF after header. */
char extra;
ASSERT(fread(&extra, 1, 1, f) == 0, "no body bytes");
fclose(f);
ASSERT(memcmp(hdr, "QECCOPS1", 8) == 0, "magic mismatch");
for (int i = 8; i < 16; i++) ASSERT_EQ_INT(hdr[i], 0);
unlink(path);
}
#undef NO_SLOT_TEST
/* ═══════════════════════════════════════════════════════════════════════════
* Main
* */
@ -1023,6 +1239,11 @@ int main(void) {
run_test_portal_save_resume_cont();
run_test_portal_checkpoint_builtin();
printf("\n[emit-stream]\n");
run_test_emit_stream_basic();
run_test_emit_stream_alloc_free();
run_test_emit_stream_empty();
printf("\n═══════════════════════════════════════════\n");
printf("Results: %d/%d passed", tests_passed, tests_run);
if (tests_failed > 0) printf(" (%d failed)", tests_failed);