Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
262 commits
Select commit Hold shift + click to select a range
f5a7327
resources: keys_prefix_chains says whether a prefix cache is open
merceod Oct 7, 2026
9e38073
kv: report an open prefix cache through keys_prefix_chains
merceod Oct 7, 2026
f1b0be5
runner: prefix_chain_keys, and extend_prefix_chains over a given key …
merceod Oct 7, 2026
5ef8de3
engine: skip the per-request prefix-chain sweep when no cache is open
merceod Oct 7, 2026
bdf055e
rust frames: RESULT_TOKENS, one frame per step for inline client values
merceod Oct 7, 2026
77d32ec
rust runtime: route an inline client signal without staging, refs or …
merceod Oct 7, 2026
77aab0c
graph runtime: RouteInput.inline_signal/inline_values and supports_in…
merceod Oct 7, 2026
db4def8
rust runtime wrapper: pass inline values, report supports_inline_emit
merceod Oct 7, 2026
95006f7
api_server: ResultTokens message type
merceod Oct 7, 2026
6661a71
wire: register result_tokens
merceod Oct 7, 2026
f6e5939
api_server: dispatch result_tokens frames to the data worker
merceod Oct 7, 2026
27322e4
data worker: detokenize inline tokens in arrival order, no read and n…
merceod Oct 7, 2026
810cf24
submodule_base: inline_client_signals hook
merceod Oct 7, 2026
1761cde
qwen3_5: the decode loop's client token rides inline
merceod Oct 7, 2026
02a6af9
engine: inline_client_signals passthrough
merceod Oct 7, 2026
d57681c
worker: hand the stop check's host tokens to the route as inline values
merceod Oct 7, 2026
21fb696
test: inline token path (wire, data worker, worker)
merceod Oct 7, 2026
a31c952
test: rust runtime inline emit
merceod Oct 7, 2026
b61b1b5
qwen3_5: decode capture buckets up to 128 rows
merceod Oct 7, 2026
51edd0c
api_server: wake the streaming handler on events instead of polling p…
merceod Oct 7, 2026
8d21448
test: a chunk from the message thread wakes the stream
merceod Oct 7, 2026
85c5367
submodule_base: step_is_input_free hook
merceod Oct 7, 2026
ba56be0
qwen3_5: decode steps declare from spans alone
merceod Oct 7, 2026
2ce4dac
engine: run the pre-plan's declared step for input-free walks
merceod Oct 7, 2026
6557266
docs: MSTAR_LAZY_PUBLISH
merceod Oct 7, 2026
080065c
worker: build and pre-plan N+2 while N+1 runs, between N's routing an…
merceod Oct 7, 2026
65ffc1a
docs: MSTAR_EARLY_SPEC
merceod Oct 7, 2026
7b21494
sampler: skip the static gather for a steady batch while other reques…
merceod Oct 8, 2026
6be4dd1
kv plan: build the paged indptr tensors through numpy
merceod Oct 8, 2026
ab3c97a
test: static gather skip with queued requests
merceod Oct 8, 2026
1025fd5
ci: list the new cpu tests
merceod Oct 8, 2026
7359e67
batched output: carry the row views the collect fast path built
merceod Oct 8, 2026
13e7943
engine: hand the row views to the collected output
merceod Oct 8, 2026
5a057b6
tensor store: batch the ownership maps, dtype index helper
merceod Oct 8, 2026
cb3d7e6
tensors: row store for a step whose outputs are row views of one batc…
merceod Oct 8, 2026
f19248a
worker: store decode row outputs through the row store
merceod Oct 8, 2026
129311f
test: merge_per_rid returns the row views
merceod Oct 8, 2026
c104c99
test: row store against the general path
merceod Oct 8, 2026
28d739d
ci: list the row store test
merceod Oct 8, 2026
760bde4
worker: build the stop check's per-rid host dicts only when read
merceod Oct 8, 2026
4e50fb7
engine: skip the unpack pass when nothing is packed
merceod Oct 8, 2026
9163255
test: lazy per-rid host dicts
merceod Oct 8, 2026
5e2b57c
ci: list the lazy per-rid test
merceod Oct 8, 2026
083cc0f
qwen3_5: MSTAR_QWEN35_DECODE_BUCKETS overrides the decode capture ladder
merceod Oct 8, 2026
5025706
docs: MSTAR_QWEN35_DECODE_BUCKETS
merceod Oct 8, 2026
a025fac
step context: constant-time padding and real-row tests
merceod Oct 8, 2026
b3a01b6
kv: batched publish snapshot under one lock, real-row test in the pag…
merceod Oct 8, 2026
91e4d28
resources: publish_snapshot_batch hook
merceod Oct 8, 2026
b2f60e6
runner: snapshot the publication per resource for the whole batch
merceod Oct 8, 2026
cb6bed1
sampler: one graph sampler per bucket and slot
merceod Oct 8, 2026
1dce205
test: step context row membership
merceod Oct 8, 2026
6cb5601
test: batched publish snapshot
merceod Oct 8, 2026
d2dcb38
test: sampler_for cache
merceod Oct 8, 2026
9f222e4
ci: list the step, snapshot and sampler tests
merceod Oct 8, 2026
fb04771
kv admit: skip the allocation call for rows whose pages already cover…
merceod Oct 8, 2026
a2d1155
engine: hoist the per-row constants out of prepare_inputs, look up th…
merceod Oct 8, 2026
dbbc572
arena: batched cleanup of collectable tensors
merceod Oct 8, 2026
50baf43
worker: send only the request entries that carry counts or stream con…
merceod Oct 8, 2026
5404251
engine: direct properties for the forward-pass wrapper's hot attributes
merceod Oct 8, 2026
bcfe673
test: batched stream consumption report
merceod Oct 8, 2026
75f5ea4
ci: list the send prep test
merceod Oct 8, 2026
c72d6af
kv commit: per-row constants hoisted, index offer only with a chain
merceod Oct 8, 2026
3a31d8b
api_server: wake the streaming handlers once per message pass
merceod Oct 8, 2026
b861dcf
test: batched handler wake-up
merceod Oct 8, 2026
f5f5303
rust runtime: env-gated timing of send_outputs (body vs GIL reacquire)
merceod Oct 8, 2026
6de4423
worker: MSTAR_SPEC_YIELD_HOLD_MS holds the decode loop's yield so arr…
merceod Oct 8, 2026
2b422b9
docs: MSTAR_SPEC_YIELD_HOLD_MS
merceod Oct 8, 2026
720587d
rust runtime: flat export of the dynamic loop iterations
merceod Oct 8, 2026
d47c22f
graph runtime: update_dynamic_loop_iters hook
merceod Oct 8, 2026
880cdbe
rust runtime wrapper: refresh loop iterations from the flat export
merceod Oct 8, 2026
cb0b9ce
worker: refresh loop iterations through the runtime hook
merceod Oct 8, 2026
aa5c467
test: update_dynamic_loop_iters matches the per-rid form
merceod Oct 8, 2026
92bed84
kv: batched prefix-chain extension off the stop check's host rows
merceod Oct 8, 2026
cb338d8
runner: batched chain extension; sweep resources that override the ho…
merceod Oct 8, 2026
da6df5b
resources: document when the chain hook is swept
merceod Oct 8, 2026
61ea439
engine: extend prefix chains from the host rows
merceod Oct 8, 2026
f66cb9b
worker: hand the host rows to the prefix-chain extension
merceod Oct 8, 2026
a490f5b
test: batched prefix-chain extension
merceod Oct 8, 2026
b369e75
ci: list the prefix batch test
merceod Oct 8, 2026
60c0ab2
engine: read the keyed walks leniently in prepare_inputs
merceod Oct 8, 2026
d35c66b
zmq communicator: non-blocking try_send
merceod Oct 8, 2026
22278c5
rust runtime: send frames with the GIL held, release it only for a pe…
merceod Oct 8, 2026
04a8f36
docs: MSTAR_RUST_SEND_TIMING
merceod Oct 8, 2026
5db372f
data worker: sort the import block
merceod Oct 8, 2026
5912708
rust runtime: the inline signal keys of a route input are optional
merceod Oct 8, 2026
4406b62
test: row store tests skip without the columnar tensor store
merceod Oct 8, 2026
4a527fa
event wakeup: a public signal for producers
merceod Oct 8, 2026
5fea346
data worker: block on the communicator's poll when idle instead of a …
merceod Oct 8, 2026
79cc69a
test: the data worker's idle wait and its wake-ups
merceod Oct 8, 2026
b261d9b
ci: list the data worker wake-up test
merceod Oct 8, 2026
bf6762c
sampler buffers: a slot-addressed last-token master written by the ca…
merceod Oct 8, 2026
9e63ef0
sampler resource: scatter the step's tokens at commit, read them back…
merceod Oct 8, 2026
bb28b08
submodule base: the device loop-back hook and its knob
merceod Oct 8, 2026
970c8ce
qwen3.5: decode input ids off the sampler's slot master
merceod Oct 8, 2026
954bace
engine: expose the node's device loop-back signals
merceod Oct 8, 2026
cf9b4f8
worker: no store, hold or tensors for a step kept on the device
merceod Oct 8, 2026
05ebf8e
docs: MSTAR_DEVICE_LOOPBACK
merceod Oct 8, 2026
5ea711f
test: the sampler's last-token master
merceod Oct 8, 2026
21f920a
test: qwen3.5 decode inputs from the sampler master
merceod Oct 8, 2026
4f0fadb
test: the worker's device loop-back decision
merceod Oct 8, 2026
d57c15d
test: a loop-back routed with no tensor keeps the loop going
merceod Oct 8, 2026
1a15e53
ci: list the device loop-back tests
merceod Oct 8, 2026
874940e
worker: early speculation on TP leaders, committing only with a head …
merceod Oct 8, 2026
0abe28b
docs: MSTAR_EARLY_SPEC on tensor-parallel nodes
merceod Oct 8, 2026
b794f72
test: a TP leader's early build takes each step's decision once
merceod Oct 8, 2026
779b9f3
ci: list the TP early speculation test
merceod Oct 8, 2026
e44975b
worker: the spec splice runs on the main thread, not the plan thread
merceod Oct 8, 2026
f5ec4d3
utils: freeze the set-up heap after a process starts
merceod Oct 8, 2026
f91a2c2
conductor: freeze the set-up heap once the workers are ready
merceod Oct 8, 2026
e2b139c
api server: freeze the set-up heap once the workers are ready, one da…
merceod Oct 8, 2026
201e484
data worker: a token put without a wake, and a wake for the frame
merceod Oct 8, 2026
13e4251
docs: MSTAR_GC_FREEZE
merceod Oct 8, 2026
2946801
test: the heap freeze and the per-frame wake
merceod Oct 8, 2026
7b2fe58
ci: list the gc freeze test
merceod Oct 8, 2026
a8a1e76
api server: the gc freeze import belongs with the module imports
merceod Oct 8, 2026
79b076e
conductor: import block sorted
merceod Oct 8, 2026
31dc82c
utils: the device loop-back knob in one place
merceod Oct 8, 2026
6422ea8
submodule base: take the loop-back knob from utils
merceod Oct 8, 2026
0628a7d
sampler resource: persist the last token only with the loop-back on, …
merceod Oct 8, 2026
2538034
qwen3.5: time the loop-back gather
merceod Oct 8, 2026
a111f51
qwen3.5: text prefill graph buckets up to 8192 tokens, with a knob
merceod Oct 9, 2026
6471b57
docs: MSTAR_QWEN35_PREFILL_TOKEN_BUCKETS
merceod Oct 9, 2026
809af26
test: the qwen3.5 bucket ladders come from the environment
merceod Oct 9, 2026
c553dee
ci: list the bucket knob test
merceod Oct 9, 2026
b00e24c
utils: tokenize a long prompt as parallel chunks, identical ids
merceod Oct 9, 2026
d19919f
qwen3.5: encode the rendered prompt through the chunked path
merceod Oct 9, 2026
723e31f
test: chunked tokenization cuts and identity
merceod Oct 9, 2026
65f24c9
ci: list the chunked tokenization test
merceod Oct 9, 2026
9b2415f
utils: wrap the chunked tokenizer signatures
merceod Oct 9, 2026
148605f
api: orjson for the SSE events, json fallback
merceod Oct 9, 2026
53ea6e9
api: iter_result_chunk_batches, one list per drain
merceod Oct 9, 2026
ecc6d44
api: chat stream sends a batch of text events as one frame
merceod Oct 9, 2026
b1a8dc3
test: result chunk batches
merceod Oct 9, 2026
931ac12
test: coalesced chat stream frames, sse line
merceod Oct 9, 2026
0b570c5
kv: host lengths iterate as numpy scalars for FlashInfer's max
merceod Oct 9, 2026
9cd55c7
test: kv plan host lengths
merceod Oct 9, 2026
bd5bf7c
runner: admit skips the resources pre_admit covered
merceod Oct 9, 2026
e0c3337
engine: phase samples for the pre-plan's declare and admit
merceod Oct 9, 2026
08141f9
worker: postprocess stamps that add up
merceod Oct 9, 2026
2c8de51
test: admit after pre_admit
merceod Oct 9, 2026
ef7eb66
submodule: host_rows on the batched output
merceod Oct 9, 2026
f80c710
worker: stage the stop rows' D2H on the gpu thread behind the step
merceod Oct 9, 2026
7d9eb7e
test: staged host rows
merceod Oct 9, 2026
56dcfa8
submodule: rows_only on the batched output, hook docs
merceod Oct 9, 2026
6f2669e
engine: rows-only collect on a device loop-back step, no tail
merceod Oct 9, 2026
6798a40
worker: rows-only steps, splice the loop-back signal as present
merceod Oct 9, 2026
a98f888
test: rows-only collect
merceod Oct 9, 2026
c5ded39
test: stub carries rows_only
merceod Oct 9, 2026
cdba6fd
test: rows-only splice
merceod Oct 9, 2026
bd75d9d
test: stub carries output_signals
merceod Oct 9, 2026
633a284
engine: no clone on a rows-only step
merceod Oct 9, 2026
627fc0e
sampler: memoized per-step views for the commit scatters
merceod Oct 9, 2026
727d3bd
test: rows-only collect takes no clone
merceod Oct 9, 2026
0014739
worker: skip the stream polls of a speculation build when no request …
merceod Oct 9, 2026
30eee5a
test: stream polls skipped only without buffers
merceod Oct 9, 2026
a717532
submodule: uniform_row_inputs hook
merceod Oct 9, 2026
4243dad
qwen3_5: the loop-back decode row is uniform
merceod Oct 9, 2026
912b2e0
engine: prepare a uniform walk with one object
merceod Oct 9, 2026
9191dcc
test: uniform loop-back row
merceod Oct 9, 2026
1e8efa0
test: engine uniform inputs
merceod Oct 9, 2026
9db4d7a
qwen3_5: a captured decode step gathers its tokens and rotary tables …
merceod Oct 9, 2026
d16a5b6
test: captured decode stages no input
merceod Oct 9, 2026
5adfacc
knobs: MSTAR_LAUNCH_SIGNAL_AFTER_COMMIT
merceod Oct 9, 2026
3932a49
worker: _exec_step, launch signal after commit behind the knob
merceod Oct 9, 2026
999eab1
docs: MSTAR_LAUNCH_SIGNAL_AFTER_COMMIT
merceod Oct 9, 2026
f6e0d22
test: launch signal placement
merceod Oct 9, 2026
b9412aa
qwen3_5: cheaper batched stop check
merceod Oct 9, 2026
6f83e10
kv: the chain extension looks a request's label up once
merceod Oct 9, 2026
e14a743
test: stop check off a reordered batch
merceod Oct 9, 2026
6799af3
api: inline tokens as ids for models that decode from ids
merceod Oct 9, 2026
44e7ba7
qwen3_5: inline postprocess takes ids
merceod Oct 9, 2026
2d91a8d
test: inline value as a list
merceod Oct 9, 2026
85bc776
knobs: MSTAR_SAMPLER_INGRAPH_SCATTER, MSTAR_SAMPLER_SLOTS
merceod Oct 9, 2026
38c240e
sampler: offset gather and the two commit scatters inside the graph, …
merceod Oct 9, 2026
8f6e60e
sampler: commit skips the scatters the graph did
merceod Oct 9, 2026
8bedee4
docs: MSTAR_SAMPLER_INGRAPH_SCATTER
merceod Oct 9, 2026
9cc1fdd
test: in-graph scatter rows and the trash row
merceod Oct 9, 2026
ee4bdbd
test: offset reset runs before the in-graph gather
merceod Oct 9, 2026
9500c8f
Revert "test: inline value as a list"
merceod Oct 9, 2026
01a929e
Revert "qwen3_5: inline postprocess takes ids"
merceod Oct 9, 2026
7d3b9fe
Revert "api: inline tokens as ids for models that decode from ids"
merceod Oct 9, 2026
fbc37e1
utils: the chunked encode turns the tokenizer crate's parallelism on
merceod Oct 9, 2026
2b13bfa
docs: MSTAR_TOKENIZE_PARALLEL
merceod Oct 9, 2026
d87e034
test: chunked encode flips TOKENIZERS_PARALLELISM
merceod Oct 9, 2026
b0e3cc8
knobs: MSTAR_TP_EARLY_SPEC
merceod Oct 9, 2026
3363443
worker: a parallel node builds early only with the knob
merceod Oct 9, 2026
1428792
docs: MSTAR_TP_EARLY_SPEC
merceod Oct 9, 2026
bb75844
test: tp early build knob
merceod Oct 9, 2026
a66c7ad
Revert "test: captured decode stages no input"
merceod Oct 9, 2026
df64756
Revert "qwen3_5: a captured decode step gathers its tokens and rotary…
merceod Oct 9, 2026
f1722eb
knobs: MSTAR_INGRAPH_DECODE_TOKENS, MSTAR_INGRAPH_DECODE_ROPE
merceod Oct 9, 2026
78e82ee
qwen3_5: in-graph decode inputs as two knobs
merceod Oct 9, 2026
3139a59
docs: the two in-graph decode input knobs
merceod Oct 9, 2026
718d2d4
test: in-graph decode input knobs
merceod Oct 9, 2026
6080d83
knobs: MSTAR_KV_CHAIN_LAZY_STEPS
merceod Oct 9, 2026
44febb1
kv: extend the prefix chains every few steps, one extend per request
merceod Oct 9, 2026
641adb4
test: lazy prefix-chain extension
merceod Oct 9, 2026
5b13cee
docs: MSTAR_KV_CHAIN_LAZY_STEPS
merceod Oct 9, 2026
eaff986
kv: a removal drains its own waiting tokens instead of a flush
merceod Oct 9, 2026
5219153
test: removal drain and handle reuse
merceod Oct 9, 2026
e906389
cuda graph: the capture hands the region its step
merceod Oct 9, 2026
00ddee5
qwen3_5: in-graph decode inputs are read at capture too
merceod Oct 9, 2026
be1dd85
test: in-graph knobs at capture
merceod Oct 9, 2026
6ccdadd
knobs: MSTAR_KV_PLAN_CACHE; lazy chain extension defaults to eager
merceod Oct 9, 2026
81d03a9
kv plan: decode write locations ride on the plan output
merceod Oct 9, 2026
ae47de9
kv: plan a steady decode batch off the previous step's plan
merceod Oct 9, 2026
8c1d391
docs: MSTAR_KV_PLAN_CACHE, lazy chain default
merceod Oct 9, 2026
d8adcea
test: kv decode plan cache
merceod Oct 9, 2026
018d1b9
knobs: MSTAR_KV_PINNED_INDPTRS
merceod Oct 9, 2026
9170497
kv plan: page-locked ring for FlashInfer's index arrays
merceod Oct 9, 2026
64d843c
kv: index arrays from the page-locked ring
merceod Oct 9, 2026
44d286e
attn: decode indices copied straight into the captured buffer
merceod Oct 9, 2026
4148f6b
docs: MSTAR_KV_PINNED_INDPTRS
merceod Oct 9, 2026
9c21758
test: pinned index ring
merceod Oct 9, 2026
2f5cbb7
kv: plan cache keeps the views, derives rows at the first hit, keys o…
merceod Oct 9, 2026
4781fc1
kv plan: lazy views and a rows tuple on the plan output
merceod Oct 9, 2026
94500cd
position: plan from the rows tuple when the KV plan carries one
merceod Oct 9, 2026
4c193f4
knobs: plan cache off until re-measured
merceod Oct 9, 2026
3fb94cb
docs: plan cache default and what was measured
merceod Oct 9, 2026
63fcd76
test: plan cache with alternating padding ids
merceod Oct 9, 2026
ebabf90
attn: the indices shortcut only for page-locked indices
merceod Oct 9, 2026
6aff3c0
kv: the per-step chain extension keeps its round-2 body
merceod Oct 9, 2026
e2698bb
knobs: pinned index ring off by default
merceod Oct 9, 2026
d2e03be
docs: pinned ring default and what was measured
merceod Oct 9, 2026
b1e3366
position: a plain list of rows when the plan carries none
merceod Oct 9, 2026
855ffbb
submodule: a node declares that it reads the device loop-back
merceod Oct 10, 2026
7936a07
qwen3_5: the LLM node reads the device loop-back
merceod Oct 10, 2026
bf86128
sampler: slot masters only for a node that reads them
merceod Oct 10, 2026
7604caa
engine: enable the sampler's loop-back masters per node
merceod Oct 10, 2026
a9c9820
test: loop-back masters follow the node's declaration
merceod Oct 10, 2026
d5d1740
docs: MSTAR_DEVICE_LOOPBACK applies to nodes that declare the read
merceod Oct 10, 2026
e3c54f5
engine: a reset pre-plan drops its kept step
merceod Oct 12, 2026
f6274b1
test: a partly dropped batch does not keep its pre-planned step
merceod Oct 12, 2026
eef4b85
kv: a snapshot of a stream reset since publishes the stream as it stands
merceod Oct 12, 2026
57ebad9
test: publish from a snapshot after a reset
merceod Oct 12, 2026
b3e3b55
worker: drop the spec yield hold, note why two slots suffice, note th…
merceod Oct 12, 2026
734972e
docs: MSTAR_SPEC_YIELD_HOLD_MS removed, MSTAR_DECODE_BUCKETS added
merceod Oct 12, 2026
5b54fc7
api: APIServerMessageBody names the message body union
merceod Oct 12, 2026
5838168
tensor store: ColumnarTensorInfo.add_row
merceod Oct 12, 2026
37f9613
tensors: the row fast path fills the columns through add_row
merceod Oct 12, 2026
3a814eb
qwen3_5: decode buckets from MSTAR_DECODE_BUCKETS, the model knob ove…
merceod Oct 12, 2026
18ea22e
merge perf/host-overhead review fixes into perf/host-overhead-2
merceod Oct 12, 2026
d2137a5
test: the fairness settings without the hold
merceod Oct 12, 2026
69abae2
merge perf/host-overhead-2 (review fixes from perf/host-overhead) int…
merceod Oct 12, 2026
6b148d4
suppress epoch updates in clear_preplan to allow cache hits; prevent …
stephen-dwq Oct 13, 2026
52e213d
dummies for sampler were never freed post-capture; added capture-time…
stephen-dwq Oct 14, 2026
0b07a85
remove INGRAPH_DECODE_TOKENS; very little perf. gain for the trouble
stephen-dwq Oct 14, 2026
09c7d87
kv plan cache: don't build views eagerly when staging a cached decode…
stephen-dwq Oct 14, 2026
f8fddec
test: add this branch's new CPU tests to cpu-core.txt
stephen-dwq Oct 14, 2026
9ce99c7
Merge origin/main into perf/host-overhead-3
stephen-dwq Oct 14, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 46 additions & 3 deletions docs/environment_variables.rst
Original file line number Diff line number Diff line change
Expand Up @@ -329,15 +329,58 @@ Worker scheduling
prefills eagerly, which is launch-bound: an eager 8k prefill on 0.8B
spends 78 ms of wall time on 36 ms of kernels. The default now reaches
8192; narrow it to save graph memory and capture time, or extend it.
* - ``MSTAR_KV_CHAIN_LAZY_STEPS``
- ``1``
- How many decode steps of sampled ids the KV manager holds back before
it extends the requests' prefix chains (the per-page keys the prefix
cache is indexed by), one extend per request per batch of steps instead
of one per step. The per-request Python of that extension was 0.3 to
0.4 ms a step at 128 rows. A page key then appears up to that many
steps late and a later commit indexes it, as the single-request path
already allows; a request that finishes in between may leave its last
page unindexed. The default ``1`` extends on every step: ``16``
measured as noise at c64/c128 on 0.8B (the extension is a small part
of the stop check's tail).
* - ``MSTAR_KV_PINNED_INDPTRS``
- ``0``
- The KV plan writes FlashInfer's index arrays (qo_indptr, kv_indptr,
kv_indices, last_page_len) into a ring of page-locked host buffers and
the decode wrapper copies the indices straight into its captured
device buffer from there, so the copies FlashInfer's ``plan`` issues
are really asynchronous. From pageable memory the driver stages each
one and FlashInfer makes the indices copy blocking. Measured neutral
to slightly negative at c32-c128 on 0.8B (the event bookkeeping per
take costs about what it saves), so it is off by default.
* - ``MSTAR_KV_PLAN_CACHE``
- ``0``
- The KV manager plans a captured decode step off the previous step's
plan when the batch is the same rows in the same order and nothing
but that step's commit touched the streams: every length is one
more, pages change only where a row crossed a page boundary, and the
five FlashInfer index arrays come from numpy instead of a per-row
Python pass. The first version measured a loss at c64/c128 on 0.8B
(batches change every step or two there, and a hit still rebuilt the
views); the reworked path keeps the views lazy and is off by default
until measured. ``0`` plans every step from the streams. ``2`` runs
both and logs a difference, for checking a run.
* - ``MSTAR_DEVICE_LOOPBACK``
- ``1``
- Whether a decode node may keep its loop-back token on the device:
the sampler writes each request's last token to a slot-addressed
master and the next step reads its input ids from it, so the worker
routes the signal with no tensor (no per-request store, hold or
cleanup per step). Only nodes that opt in (Qwen3.5 decode) and only
when the sampler has graph buffers; ``0`` keeps every node on the
per-request tensor path.
cleanup per step). Only nodes that declare the read
(``reads_device_loopback``: Qwen3.5 decode) and only when the sampler
has graph buffers; the sampler keeps the masters for those nodes
alone, so a node that takes its tokens on the host (Whisper's
decoder) no longer pays the eager-step master write, a small
synchronous host-to-device copy per step. ``0`` keeps every node on
the per-request tensor path.
* - ``MSTAR_INGRAPH_DECODE_ROPE``
- ``0``
- A captured decode step builds its rotary tables inside the graph from
the position resource's planned positions instead of staging them.
Experiment knob, measured and gated on its own.
* - ``MSTAR_SAMPLER_INGRAPH_SCATTER``
- ``0``
- The captured sampler gathers its RNG offsets from the slot masters
Expand Down
11 changes: 8 additions & 3 deletions mstar/engine/cuda_graph_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ def ensure(self, key: str, bs: int) -> list[int]:
held = self._held.setdefault(key, [])
rids = self.handles(key, bs)
for rid in rids[len(held):]:
self._step_runner.ingest_request(rid)
self._step_runner.ingest_capture_row(rid)
held.append(rid)
return rids

Expand Down Expand Up @@ -1271,7 +1271,7 @@ def _capture_one(self, shape: PiecewiseCaptureShape, slot: int) -> None:
dummy_rids, shape.seq_lens, self._bucket(shape), capture=True,
slot=slot
)
call = self._call_inputs(static_inputs, dummy_rids)
call = self._call_inputs(static_inputs, dummy_rids, step)

fn = self._config.capture_fn
if self._config.compile:
Expand Down Expand Up @@ -1319,19 +1319,24 @@ def _call_inputs(
self,
static_inputs: dict[str, torch.Tensor],
step_ids: list[int],
step=None,
) -> PiecewiseCallInputs:
"""What the region is handed, over the padded capture batch.

Built once, for the capture: the region's Python runs only there, so
the rows are the runner's padding ids and the only thing a replay
changes is the contents of the static buffers.
changes is the contents of the static buffers. ``step`` is the
capture's declaration, so the region can tell it runs on a leased
slot (its context names the lease) and record the in-graph reads of
the slot's buffers a replay relies on.
"""
return PiecewiseCallInputs(
static_inputs=static_inputs,
engine_inputs=ModelInputsFromEngine(
request_ids=list(step_ids),
per_request_info=dummy_metadata(step_ids, PIECEWISE_WALK),
resources=dict(self._resources),
step=step,
),
kwargs=self._config.forward_kwargs,
)
Expand Down
7 changes: 7 additions & 0 deletions mstar/engine/engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,13 @@ def load_model(
resources=resources
)
submodule.bind_node_resources(resources)
if getattr(submodule, "reads_device_loopback", False):
# the sampler keeps its slot masters only for a node that
# reads them back on the device (see NodeSubmodule)
for resource in resources.values():
enable = getattr(resource, "enable_device_loopback_reader", None)
if enable is not None:
enable()

def _compile_submodules(self) -> None:
"""Apply torch.compile to submodule forward paths.
Expand Down
12 changes: 12 additions & 0 deletions mstar/engine/resources/attn/wrappers.py
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,18 @@ def plan(
Inputs may be on CPU; see prefill wrapper's plan docstring.
"""
n_req = paged_kv_indptr.shape[0] - 1
if (
self.use_cuda_graph and paged_kv_indices.device.type != "cuda"
and paged_kv_indices.is_pinned()
):
# FlashInfer copies host indices with a blocking copy; page-locked
# indices (the KV plan's ring, MSTAR_KV_PINNED_INDPTRS) go in one
# non-blocking copy into its own buffer instead, and its copy_ of
# that buffer onto itself is a no-op. Pageable indices keep
# FlashInfer's path, so the knob is a full toggle.
n = paged_kv_indices.shape[0]
self._paged_kv_indices_buf[:n].copy_(paged_kv_indices, non_blocking=True)
paged_kv_indices = self._paged_kv_indices_buf[:n]

if self.enable_nvtx:
from mstar.utils.profiler import range_pop, range_push
Expand Down
4 changes: 4 additions & 0 deletions mstar/engine/resources/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,10 @@ def fingerprint(self) -> bytes | None:
def ingest_request(self, rid: str, overrides: ResourceReqConfig | None):
return

def ingest_capture_row(self, rid: str):
"""Open a CUDA graph capture padding row; by default, as a request."""
self.ingest_request(rid, None)

def remove_request(self, rid: str):
return

Expand Down
Loading
Loading