code wiki / (root) / nx_batch_scheduler.nx

nx_batch_scheduler.nx

buildroot/runtime/nx_batch_scheduler.nx

14317 B369 linesdepth 2pulls 2 transitivereach 2 importersview sourcekind librarytopic batch
docsdependenciesstructsconstsfunctions

about

nx_batch_scheduler.nx -- H2 continuous batching (bits-up). Per NISHI_ELDER_AI_OFF_DOCKER_2026_05_20.md ยง2.1 H2: pack pending requests at TOKEN level not request level so the GPU stays saturated. vLLM + TGI ship this pattern at scale (~10x throughput over naive request-by-request scheduling). V1 mechanics: N-slot fixed scheduler. Each slot holds at most one active request (sequence_id + tokens_remaining + state). admit() places a request in a free slot OR queues it. step() reports the slots currently in RUNNING state -- those are the active batch for the next forward pass. complete() marks a slot DONE. recycle() reclaims DONE slots and drains the pending queue into the newly-free slots. The "continuous" part: at each scheduler step, the active batch composition CAN CHANGE. A slot whose request finished at token N gets reclaimed and refilled with a queued request at token 0 -- so the GPU forward pass never has to wait for the whole batch to finish. Pure substrate logic. No Linux features. Composes with shipped nx_kv_arena (request's sequence holds its KV pages) and the future actor cardinal (sequences serve text + image-prompt + any other endpoint). V1 honest scope: - Fixed slot count (N <= NX_BATCH_MAX_SLOTS = 32) - Fixed pending queue (M <= NX_BATCH_MAX_PENDING = 64) - First-come-first-served queue ordering (no priority yet) - No per-sequence preemption (a slot runs to DONE; preemption queued for V2 when attention-class arbitration lands) genealogy_id: vllm_continuous_batching_2023 + tgi_2023 + cardinal_2026-05-20_elder_ai_off_docker + cardinal_2026-05-20_bits_up_nishi_not_linux lineage_id: substrate_batch_scheduler_v1 nx_capability_manifest: variant_class: batch_scheduler

dependencies 1 imports · 2 importers

nx_syscalls.nx nx_batch_scheduler.nx nx_batch_scheduler_test.nx nx_hackers_algo_compose_test.nx

imports: nx_syscalls.nx

imported by: nx_batch_scheduler_test.nxnx_hackers_algo_compose_test.nx

structs

107struct NxBatchSlot
114struct NxBatchScheduler

consts

65const NX_BATCH_MAX_SLOTS: i64 = 32
66const NX_BATCH_MAX_PENDING: i64 = 64
69const NX_SLOT_FREE: i64 = 0
70const NX_SLOT_RUNNING: i64 = 1
71const NX_SLOT_DONE: i64 = 2
72const NX_SLOT_N_STATES: i64 = 3
87const NX_BATCH_OK: i64 = 0
88const NX_BATCH_BAD_INPUT: i64 = 1
89const NX_BATCH_QUEUED: i64 = 2 // admitted to queue, not slot
90const NX_BATCH_FULL: i64 = 3 // slots + queue both full
91const NX_BATCH_SLOT_NOT_RUNNING: i64 = 4
92const NX_BATCH_BAD_SLOT: i64 = 5
93const NX_BATCH_TAMPER: i64 = 6
94const NX_BATCH_N_VERDICTS: i64 = 7
103const NX_BATCH_CANARY_PRE: i64 = 0x4E5842415453504C // "NXBATSPL"
104const NX_BATCH_CANARY_POST: i64 = 0x4E58424154454E44 // "NXBATEND"

functions

74func nx_slot_state_is_valid(s: i64) -> i64
called by 1: main
96func nx_batch_verdict_is_valid(v: i64) -> i64
called by 1: main
131func nx_batch_scheduler_new(max_slots: i64, max_pending: i64) -> *NxBatchScheduler
called by 2: mainmain calls 1: sys_mmap
163func nx_batch_scheduler_is_valid(sch: *NxBatchScheduler) -> i64
178func _batch_find_free_slot(sch: *NxBatchScheduler) -> i64
193func nx_batch_scheduler_admit(
222func nx_batch_scheduler_step(
called by 1: main calls 1: nx_batch_scheduler_is_valid
247func nx_batch_scheduler_tick(
271func nx_batch_scheduler_complete(
called by 1: main calls 1: nx_batch_scheduler_is_valid
292func nx_batch_scheduler_recycle(sch: *NxBatchScheduler) -> i64
332func nx_batch_scheduler_n_running(sch: *NxBatchScheduler) -> i64
337func nx_batch_scheduler_n_pending(sch: *NxBatchScheduler) -> i64
called by 1: main calls 1: nx_batch_scheduler_is_valid
342func nx_batch_scheduler_n_done(sch: *NxBatchScheduler) -> i64
called by 1: main calls 1: nx_batch_scheduler_is_valid
347func nx_batch_scheduler_slot_state(sch: *NxBatchScheduler, slot_idx: i64) -> i64
355func nx_batch_scheduler_slot_request_id(sch: *NxBatchScheduler, slot_idx: i64) -> i64
called by 1: main calls 1: nx_batch_scheduler_is_valid
363func nx_batch_scheduler_slot_tokens_remaining(sch: *NxBatchScheduler, slot_idx: i64) -> i64
called by 1: main calls 1: nx_batch_scheduler_is_valid