engine: bound shutdown drain for mlx generate (#46)#125
Conversation
Make the engine-thread non-interruptible window under cancel/shutdown explicit, polled, and proven: - Test-facing gen hooks (prefill/decode/seed) with poll -> hook -> re-poll - Seed-forward cancel/shutdown poll before last-prompt-token forward - GPU deadline tests for mid-prefill and mid-decode cancel/shutdown - Multi-chunk prefill grain via tiny_qwen3 max_position 2048 (R2b) - destroy-join bound under mid-prefill barrier (helper-thread release) Residual window remains one prefill chunk or one pipelined decode step. Closes #46; Stage F (#57) stays open.
Code review: PR #125 — engine: bound shutdown drain for mlx generate (#46)Overall: approve with nits. This is a clean Stage-F slice of #46. The production change is small and well-targeted, the poll contract is explicit, and the GPU test matrix actually pins the cancel/shutdown sites that matter. I do not see a blocking correctness bug. What works well
Findings1. Residual-window docs omit seed (nit / docs)
Seed is a third non-interruptible site (1-token forward + logits). Smaller than a prefill chunk, but the bound statement should name it so the three poll sites and the three residual cases stay 1:1. Suggest aligning
2. Deadline tests prove control-plane latency, not mlx residual wall-clock (nit / tests)
That correctly proves: "cancel observed at poll site → It does not prove: "one 512-token prefill chunk (or one pipelined decode step) on a real checkpoint finishes inside 2000 ms / HTTP drain." Wall-clock residual still scales with model size; second SIGINT remains necessary for that. The PR body is mostly honest about this — please add a one-line comment above 3. Mid-decode cancel/shutdown should assert zero tokens (suggestion / tests)Prefill and seed paths assert Please drain and assert 4. Missing shutdown twin for seed barrier (nit / tests)Prefill and decode have cancel and shutdown variants. Seed only has 5.
|
Snapshot gen_hooks for the duration of handle_generate_real; tighten decode cancel/shutdown asserts; add shutdown seed twin and hooks stability test; name seed in residual docs; honesty comment on MLXD_TEST_DRAIN_BOUND_MS control-plane bound.
|
Thanks - agree with the Approve-with-nits calibration. Addressed on 545690a:
5b declined as a hard ban: 6: left
|
Summary
Closes #46 (Stage F slice only; #57 stays open).
Make the engine-thread non-interruptible window under cancel/shutdown explicit, polled, and proven:
MLXD_PREFILL_CHUNK=512) with shutdown/cancel polled before every chunk.Cycle 0 audit
handle_generate_realfwd_rope_freqs_buildis head_dim-based, not max_pos-length - safe for R2bdrain_deadline_msProduction changes
engine_gen_hooks_t+engine_set_gen_hooks(test/support; real path only; stub ignores)on_before_seedhookengine.handCLAUDE.mdTests
CPU (
test_engine.c):test_gen_hooks_default_nulltest_gen_hooks_stub_ignoresGPU (
test_engine_gpu.c):test_prefill_hook_fires_once_short_prompttest_decode_hook_fires_per_steptest_cancel_mid_decode_within_deadlinetest_shutdown_mid_decode_within_deadlinetest_cancel_mid_prefill_within_deadlinetest_shutdown_mid_prefill_within_deadlinetest_cancel_between_prefill_and_seedtest_prefill_multi_chunk_hook_positionstest_cancel_after_first_prefill_chunktest_destroy_joins_within_deadline_mid_prefillExisting B3.11 cancel/shutdown tests retained.
Fixture
tiny_qwen3{,_sharded,_tied}max_position_embeddings: 512 -> 2048tools/gen_tiny_ckpt.cQWEN3 recipe updated so regen stays consistenttest_oversized_promptexpects 2049/2048Test plan
make test(44 passed)make tests/test_engine_gpu && ./tests/test_engine_gpu(all engine: bound shutdown drain for non-interruptible mlx ops #46 cases green)