Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
f0f89b8
fix(bench): record prompt evidence and warn on short-prompt prefill
Kaden-Schutt Sep 3, 2026
0f90851
style: rustfmt changed files
Kaden-Schutt Sep 3, 2026
e68cf78
fix(bench): read prompt length from prefill_tokens + cached_tokens
Kaden-Schutt Sep 3, 2026
f8ef51e
style: rustfmt changed files
Kaden-Schutt Sep 3, 2026
4dc2234
chore: refresh crate maps (check-crate-maps --write)
Kaden-Schutt Sep 3, 2026
8f3a9b6
docs(agents): restore the --reasoning-on row the --prompt-file hunk d…
Kaden-Schutt Sep 4, 2026
3149be7
hw-gate: merge PR #689 (fix(bench): --prompt-file, prompt evidence in…
hipfire-fable[bot] Sep 4, 2026
8bd5e34
fix(prefill): share MQ-V2 admit rule between llama and qwen35 gates
Kaden-Schutt Sep 3, 2026
db9c1b2
fix(mq4v2): discriminating disjoint-halves GEMM parity arm + doc corr…
Kaden-Schutt Sep 3, 2026
077aac5
style: rustfmt changed files
Kaden-Schutt Sep 3, 2026
8d4450b
chore: refresh crate maps (check-crate-maps --write)
Kaden-Schutt Sep 3, 2026
d096147
fix(dflash): make draft ctors transactional on partial failure
Kaden-Schutt Sep 3, 2026
624d0cd
fix(generate): roll back live state on make_spec_emitter error
Kaden-Schutt Sep 3, 2026
ace8407
fix(generate): unify spec ctx-cap guards and report ctx-exhausted as …
Kaden-Schutt Sep 3, 2026
06e75a9
style: rustfmt changed files
Kaden-Schutt Sep 3, 2026
2d2d621
test(generate): move ctx-exhausted terminal test to its own file
Kaden-Schutt Sep 3, 2026
3babc96
chore: refresh crate maps (check-crate-maps --write)
Kaden-Schutt Sep 3, 2026
4e360fb
fix(runtime): llama never admits MQ-V2 to batched prefill; forward_pr…
Kaden-Schutt Sep 4, 2026
136e3f0
fix(dflash): new_windowed parks each allocation in the scratch so a m…
Kaden-Schutt Sep 4, 2026
d14b3a0
hw-gate: merge PR #690 (fix(mq4v2): one MQ-V2 prefill admit rule for …
hipfire-fable[bot] Sep 4, 2026
048c0f2
merge beta into fix/dflash-robustness; regenerate hipfire-runtime cra…
Kaden-Schutt Sep 4, 2026
31dd5e3
chore: refresh hipfire-runtime crate map (check-crate-maps --write)
Kaden-Schutt Sep 4, 2026
aad8815
hw-gate: merge PR #691 (fix(dflash): transactional draft ctors, emitt…
Kaden-Schutt Sep 4, 2026
8678929
feat(registry): pair DFlash drafts as dflash sidecars (audit-Dflash B…
Kaden-Schutt Sep 3, 2026
351c326
feat(load): resolve registry dflash sidecar; on fails closed (audit-D…
Kaden-Schutt Sep 3, 2026
4eb5209
docs: describe registry-declared dflash sidecars (audit-Dflash Broken 1)
Kaden-Schutt Sep 3, 2026
9c6dbd2
style: rustfmt changed files
Kaden-Schutt Sep 3, 2026
faf7b6a
chore(daemon): keep daemon_lines under the leanup ratchet
Kaden-Schutt Sep 3, 2026
51409f1
chore: refresh crate maps (check-crate-maps --write)
Kaden-Schutt Sep 3, 2026
15851eb
chore: refresh loader/runtime crate maps
Kaden-Schutt Sep 3, 2026
241c548
fix(registry): resolve a model given by path to its entry
Kaden-Schutt Sep 3, 2026
2432fbf
fix(cli): look the DFlash sidecar up in the models dir, not beside th…
Kaden-Schutt Sep 3, 2026
e344d61
style: rustfmt changed files
Kaden-Schutt Sep 3, 2026
b9d3b12
fix(serve): report a path-requested model by its path, not its tag
Kaden-Schutt Sep 3, 2026
dbe8896
registry: pair DFlash drafts only where the 24 GB budget closes
Kaden-Schutt Sep 3, 2026
34053f9
fix(cli): rm keeps a DFlash sidecar that another installed target sti…
Kaden-Schutt Sep 4, 2026
35d209a
fix(loader): drain the GPU pool when a qwen35 load is rolled back
Kaden-Schutt Sep 4, 2026
c86712d
fix(cli): a path gets registry identity only when it is the installed…
Kaden-Schutt Sep 4, 2026
397a366
Merge beta into fix/dflash-registry-pairing
Kaden-Schutt Sep 4, 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
44 changes: 23 additions & 21 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -220,27 +220,27 @@ works, what to measure, what counts as pass/fail.

### Pull the model + draft you want to test

Targets and drafts are independent pulls — drafts auto-discover their
target by filename when the daemon loads:
`hipfire pull <tag>` fetches the target plus its registry-declared
DFlash draft sidecar (same mechanism as the MTP/DSpark sidecars):

```bash
# 27B Qwen 3.5 (the canonical perf-test target):
hipfire pull qwen3.5:27b # 15 GB target
hipfire pull qwen3.5:27b-draft # 0.92 GB DFlash draft
hipfire pull qwen3.5:27b # 15 GB target + 0.92 GB DFlash draft sidecar

# 27B Qwen 3.6 (refresh):
hipfire pull qwen3.6:27b # 15 GB target
hipfire pull qwen3.6:27b-draft # 0.92 GB DFlash draft
hipfire pull qwen3.6:27b # 15 GB target + 0.92 GB DFlash draft sidecar

# 9B Qwen 3.5 (smaller, faster sanity-check):
hipfire pull qwen3.5:9b # 5.3 GB target
hipfire pull qwen3.5:9b-draft # 0.55 GB DFlash draft
hipfire pull qwen3.5:9b # 5.3 GB target + 0.55 GB DFlash draft sidecar
```

Files land at `~/.hipfire/models/<canonical-name>` matching the
daemon's auto-discovery pattern (`qwen3{ver}-{size}-dflash-{quant}.hfq`).
**Do not rename.** Renaming breaks the auto-discovery and DFlash falls
back to AR silently.
Standalone `*-draft` tags (`hipfire pull qwen3.5:27b-draft`) still work —
they address the same file for anyone who wants the draft alone.

Files land at `~/.hipfire/models/<canonical-name>`.
**Do not rename.** Load resolves the draft by its registry-declared
filename; renaming breaks the pairing — `dflash_mode auto` then runs AR
(one warning line), `on` fails the load.

### Verify md5s after pull (paranoid mode)

Expand Down Expand Up @@ -330,7 +330,8 @@ Standalone: `cargo run --release -p hipfire-runtime --example encode_prompt -- M
- `hipfire-models/qwen3.6-27b/qwen36-27b-dflash-mq4.hfq` (+ the 3.6 27B
target `hipfire-models/qwen3.6-27b/qwen3.6-27b.mq4`)

Pullable via `hipfire pull qwen3.{5,6}:{9b,27b}-draft` and `hipfire pull qwen3.6:27b`.
`hipfire pull <target>` fetches the target plus its draft sidecar;
standalone drafts stay pullable via `hipfire pull qwen3.{5,6}:{9b,27b}-draft`.

---

Expand All @@ -355,6 +356,7 @@ hipfire bench <model> --runs 5 --warmups 3 --max-tokens 128 --json
| `--spec` | `off`/`dflash`/`mtp`/`ngram`/`dspark`/`auto` |
| `--backend` | `noslots` (sequential daemon) / `slots` / `batch` / `both` |
| `--workload` | `stateless` / `multiturn` / `both` |
| `--prompt-file PATH` | verbatim prompt bytes for the run; JSON records `prompt_tokens`/`prompt_md5`/`prompt_chars` plus a `warnings` caveat below 256 tokens |
| `--kv-mode`, `--kv-backend` | KV format and allocator |
| `--reasoning-on` | off by default: a reasoning model cannot close `<think>` inside the token budget, and the daemon fails that turn closed |

Expand Down Expand Up @@ -429,17 +431,17 @@ reassurance.
If you're testing an actual user UX flow:

```bash
hipfire pull qwen3.5:9b
hipfire pull qwen3.5:9b-draft
hipfire pull qwen3.5:9b # target + draft sidecar in one pull
hipfire config set dflash_mode auto # opt in (default since 2026-04-26: off)
hipfire run qwen3.5:9b "Write a Python function to find the longest substring without repeating characters"
# expected: daemon logs '[hipfire] DFlash draft detected: ...'
# expected: loader logs 'DFlash draft loaded: ...'
# response generates at ≥250 tok/s on a 9B target with a paired draft
```

Without the `dflash_mode auto` config, `hipfire run` runs pure AR
even when a paired draft is on disk — the daemon explicitly logs
`[hipfire] DFlash disabled (dflash_mode=off).` This is the "I pulled
even when a paired draft is on disk. `dflash_mode on` instead requires
the sidecar and fails the load when it is missing; `developer.dflash_draft`
or `run --model-draft` overrides the sidecar. This is the "I pulled
the draft but DFlash isn't firing" pitfall.

---
Expand Down Expand Up @@ -584,8 +586,8 @@ against the A3B MoE DFlash perfmaxx line.
| 3.6-A3B DFlash 68.6 tok/s vs AR 135 tok/s (50% loss) | 3.6 draft trained on 3.5 traces; target distribution mismatch on code. τ=1.22 on hard code. | Use AR mode for 3.6-A3B. Draft mismatch is expected and no 3.6 retrain is planned — Path C (`feat/mtp-dflash-training`) is dead/out-of-scope, not a forthcoming fix. 3.5-A3B DFlash works (τ=4.91). |
| `hipMalloc out of memory` at hidden_rb | Long ctx (≥16K real tokens) + 27B + asym3 = tight on 24 GB | Reduce ctx, use a smaller target, or wait for the bounded-rolling-buffer trick (roadmap) |
| `tok/s` below expected on long-ctx | KV cache growth — prefill is fine but decode slows past ~2K | Test at small ctx first, then scale |
| daemon doesn't auto-find draft | Filename doesn't match `qwen3{ver}-{size}-dflash-{quant}.hfq` | Don't rename the file after pull |
| `[hipfire] DFlash disabled (dflash_mode=off)` | Default flipped to `off` in 35265c6 (post-2026-04-26). Pulling a draft does NOT auto-enable DFlash anymore. | `hipfire config set dflash_mode auto` (or `on`); or per-model `hipfire config qwen3.5:9b set dflash_mode on` |
| daemon doesn't pair a pulled draft | Renamed draft file, or pulled before the sidecar existed | Don't rename files after pull; re-run `hipfire pull <tag>` to fetch the registry-declared sidecar |
| `[hipfire-daemon] dflash_mode=off — skipping draft load` | Default flipped to `off` in 35265c6 (post-2026-04-26). Pulling a draft does NOT auto-enable DFlash anymore. | `hipfire config set dflash_mode auto` (or `on`); or per-model `hipfire config qwen3.5:9b set dflash_mode on` |
| "Numbers don't match the README" | Forgot `HIPFIRE_NORMALIZE_PROMPT=1` (pre-2026-04-26) | Now default ON. Pull latest. If you opted out via `prompt_normalize=false`, that overrides the default — flip back. |
| "27B DFlash regressed 30-40% suddenly" | PR #32 (cleanup-dead-wmma-kernels) on master removed `gemm_hfq4g256_residual_wmma{,2,_k4}.hip` thinking dead. Dispatch fell back to slower variants. | Verify against canonical 199 tok/s @ max=120 with default flags. If kernel files missing in `kernels/src/`, `git checkout` from a known-good commit (see commit 9a2c667 for the full recovery context). |
| `HIPFIRE_GRAPH=1` reports plausible tok/s but output is garbage | Dangling stack-pointer kernargs from raw `self.hip.launch_kernel(...)` calls in `forward_scratch_layers` (kv_cache_write_*, attention_flash_*, fused_qkv_hfq4g256, rmsnorm_batched, rope_partial_interleaved_f32, gated_delta_net_q8, etc.) — captured pointers dangle past `end_graph_capture` | Bench tok/s alone never proves graph correctness. Always coherence-gate or eyeball under `HIPFIRE_GRAPH=1`. Fix: migrate every raw-launch helper used in forward_scratch_layers to `launch_maybe_blob` (model after `conv1d_silu_split_f32_n`). |
Expand All @@ -602,7 +604,7 @@ against the A3B MoE DFlash perfmaxx line.
| `HIPFIRE_PROMPT_HEAT_LIMIT` | Max rows in heat dump | 64 |
| `HIPFIRE_KV_MODE` | Override kv_cache config | (config) |
| `HIPFIRE_ATTN_FLASH` | Override flash_mode config | (config) |
|`HIPFIRE_DFLASH_DRAFT`|Force a specific draft path. Empty string = explicit opt-out|(filename auto-match alongside target)|
|`HIPFIRE_DFLASH_DRAFT`|Force a specific draft path, overriding the registry sidecar. Empty string = explicit opt-out|(unset: registry sidecar when `dflash_mode` is `auto`/`on`)|
|`HIPFIRE_DFLASH_CTX_CAP`|Max rows for draft context-indexed structures (target_hidden, draft K/V caches, hidden ring). Bounds draft-side VRAM on large-`max_seq` serve loads; over-cap requests fall back to AR (identical output, slower). `0` = uncapped legacy.|8192|
|`HIPFIRE_DFLASH_WINDOW`|Windowed draft context (NInfer pattern): SWA over the last W rows on draft layers 0..n-2 + full-attention last layer reaching min(physical_cap, 4W). Draft VRAM pins at W regardless of `max_seq`; past-W requests degrade τ instead of falling back to AR. Refused with CASK eviction. `0`/unset = Legacy (cap + AR fallback).|0 (off)|
| `HIPFIRE_LM_HEAD_F16` | `auto`/`native` keeps qt=1 lm_head as F16; `f32`/`legacy` expands to F32 | auto/native |
Expand Down
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions crates/hipfire-arch-qwen35/map.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ _Generated by `scripts/check-crate-maps.py` from the tree — do not edit inside
| [`src/qwen35/ep_batch.rs`](src/qwen35/ep_batch.rs) | 4,800 | 20 | 7 |
| [`src/qwen35/forward.rs`](src/qwen35/forward.rs) | 6,255 | 31 | 12 |
| [`src/qwen35/load.rs`](src/qwen35/load.rs) | 4,906 | 10 | 0 |
| [`src/qwen35/prefill.rs`](src/qwen35/prefill.rs) | 9,312 | 11 | 48 |
| [`src/qwen35/prefill.rs`](src/qwen35/prefill.rs) | 9,381 | 11 | 49 |
| [`src/qwen35/weights.rs`](src/qwen35/weights.rs) | 1,971 | 43 | 10 |
| [`src/qwen35.rs`](src/qwen35.rs) | 63 | 7 | 0 |
| [`src/scheduler.rs`](src/scheduler.rs) | 142 | 3 | 4 |
Expand Down Expand Up @@ -97,6 +97,6 @@ _Generated by `scripts/check-crate-maps.py` from the tree — do not edit inside

### Totals

- 29 modules · 57,281 lines · 436 public items · 189 tests · 4 examples
- 29 modules · 57,350 lines · 436 public items · 190 tests · 4 examples

<!-- crate-map:generated:end -->
143 changes: 106 additions & 37 deletions crates/hipfire-arch-qwen35/src/qwen35/prefill.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1543,17 +1543,16 @@ pub(crate) fn is_batchable_la(dt: DType, arch: &str) -> bool {
// (gfx1100/1101/1102/1150/1151 + gfx1200/1201) but gate the gfx11 half
// behind HIPFIRE_MQV2_GFX11_WMMA != "0" — setting
// HIPFIRE_MQV2_GFX11_WMMA=0 restores the per-token fallback ONLY on
// gfx11, leaving gfx12 untouched. Lockstep with the HasWmma predicate
// on GemmMq*G256V2* keys and with gemm_mq*g256v2's has_wmma() guard.
// gfx11, leaving gfx12 untouched. Delegates to the shared
// `hipfire_runtime::llama::mqv2_wmma_batchable` rule (shared home for
// the dtype/arch/kill-switch set). NOTE: `llama::is_batchable_la` does
// NOT delegate to it — the llama chunk path has no V2 arms, so llama
// refuses V2 everywhere; only this qwen35 caller admits V2. Lockstep with
// the HasWmma predicate on GemmMq*G256V2* keys and with
// gemm_mq*g256v2's has_wmma() guard.
// MQ4CG256 (qt45) remains gfx12-only until its gfx11 sibling lands.
let mqv2_with_wmma = matches!(
let mqv2_with_wmma = llama::mqv2_wmma_batchable(
dt,
DType::MQ4G256V2
| DType::MQ6G256V2
| DType::MQ5G256V2
| DType::MQ3G256V2
| DType::MQ2G256V2
) && mqv2_gfx11_wmma_enabled_from_env(
hipfire_config::developer_var("HIPFIRE_MQV2_GFX11_WMMA")
.ok()
.as_deref(),
Expand Down Expand Up @@ -1582,24 +1581,6 @@ pub(crate) fn is_batchable_la(dt: DType, arch: &str) -> bool {
|| bf16_with_gfx942
}

/// Helper for MQ2/3/4/5/6G256V2 (qt44,47-50) batched prefill admit: gfx12 always, gfx11
/// gated by HIPFIRE_MQV2_GFX11_WMMA != "0". Public for testability, mirrors
/// `mq6_batched_admit_enabled_from_env` / `q8_prefill_wmma_enabled_from_env`.
/// `value` is the raw env var (None = unset → default ON); only Some("0")
/// disables the gfx11 path. Gfx12 is unaffected by the env var.
pub(crate) fn mqv2_gfx11_wmma_enabled_from_env(value: Option<&str>, arch: &str) -> bool {
let gfx11_enabled = value != Some("0");
if matches!(arch, "gfx1200" | "gfx1201") {
true
} else if matches!(
arch,
"gfx1100" | "gfx1101" | "gfx1102" | "gfx1150" | "gfx1151"
) {
gfx11_enabled
} else {
false
}
}
/// Single source of truth for per-layer batchability and checked geometry.
/// Called by `validate_ep_batch_compatibility`, `prefill_batch_pbs_eligible`,
/// `fa_batched_ok` guard, and later EP state preflight. Validates every
Expand Down Expand Up @@ -8152,44 +8133,44 @@ mod tests {
#[test]
fn qwen35_is_batchable_la_mq4_v2_env_escape() {
// HIPFIRE_MQV2_GFX11_WMMA=0 restores fallback ONLY on gfx11; gfx12
// remains admitted. Use the helper directly to avoid global env
// remains admitted. Use the shared helper directly to avoid global env
// mutation flakiness in parallel tests — is_batchable_la delegates
// to this helper verbatim.
// to `llama::mqv2_wmma_batchable`, which calls this helper verbatim.
for arch in ["gfx1100", "gfx1101", "gfx1102", "gfx1150", "gfx1151"] {
assert!(
!mqv2_gfx11_wmma_enabled_from_env(Some("0"), arch),
!llama::mqv2_gfx11_wmma_enabled_from_env(Some("0"), arch),
"env=0 should disable {arch}"
);
assert!(
mqv2_gfx11_wmma_enabled_from_env(None, arch),
llama::mqv2_gfx11_wmma_enabled_from_env(None, arch),
"unset should enable {arch}"
);
assert!(
mqv2_gfx11_wmma_enabled_from_env(Some("1"), arch),
llama::mqv2_gfx11_wmma_enabled_from_env(Some("1"), arch),
"env=1 should enable {arch}"
);
}
for arch in ["gfx1200", "gfx1201"] {
assert!(
mqv2_gfx11_wmma_enabled_from_env(Some("0"), arch),
llama::mqv2_gfx11_wmma_enabled_from_env(Some("0"), arch),
"gfx12 unaffected by env=0 on {arch}"
);
assert!(
mqv2_gfx11_wmma_enabled_from_env(None, arch),
llama::mqv2_gfx11_wmma_enabled_from_env(None, arch),
"gfx12 enabled without env on {arch}"
);
}
for arch in ["gfx1010", "gfx942", "gfx1030", "gfx1103", "gfx1152"] {
assert!(
!mqv2_gfx11_wmma_enabled_from_env(None, arch),
!llama::mqv2_gfx11_wmma_enabled_from_env(None, arch),
"non-WMMA {arch} must never admit"
);
assert!(
!mqv2_gfx11_wmma_enabled_from_env(Some("0"), arch),
!llama::mqv2_gfx11_wmma_enabled_from_env(Some("0"), arch),
"non-WMMA {arch} with env=0"
);
assert!(
!mqv2_gfx11_wmma_enabled_from_env(Some("1"), arch),
!llama::mqv2_gfx11_wmma_enabled_from_env(Some("1"), arch),
"non-WMMA {arch} with env=1"
);
}
Expand Down Expand Up @@ -8241,6 +8222,94 @@ mod tests {
assert_eq!(rdna_compute::MQ4V2_GROUP_BYTES, 136);
}

#[test]
fn mqv2_admit_llama_qwen35_lockstep() {
// True contract (PR #690 hw-gate regression): llama and qwen35 agree
// on every NON-V2 dtype, but for the V2 family they deliberately
// diverge — qwen35's `forward_prefill_chunk` has V2 dispatch arms
// (206 hits) so it admits V2 via the shared
// `llama::mqv2_wmma_batchable` rule, while llama's chunk path has no
// V2 arms (`qkv_is_mq`/`wo_is_mq`/`ffn_is_mq`/`w_down_is_mq` list
// only V1 dtypes) so `llama::is_batchable_la` refuses V2 everywhere
// and stays on per-token decode. Admitting V2 to the llama path
// would skip the FWHT rotate and run V1 `hfq4g256` launchers on V2
// blobs — silently incoherent prefill.
// Non-V2 agreement across the 5-arch sample.
let non_v2 = [
DType::MQ4G256,
DType::HFQ4G256,
DType::MQ6G256,
DType::MQ3G256,
DType::MFP4G32,
DType::Q8_0,
];
for dt in non_v2 {
for arch in ["gfx1100", "gfx1151", "gfx1201", "gfx1030", "gfx1010"] {
assert_eq!(
llama::is_batchable_la(dt, arch),
is_batchable_la(dt, arch),
"lockstep drift for {dt:?} on {arch}"
);
}
}
// V2 divergence: qwen35 admits on gfx11/gfx12 (kill-switch at its
// default ON here — both gates read `HIPFIRE_MQV2_GFX11_WMMA`
// identically, so with the var unset gfx11 admits), refuses
// pre-WMMA; llama refuses on all 5 arches.
let v2 = [
DType::MQ4G256V2,
DType::MQ6G256V2,
DType::MQ5G256V2,
DType::MQ3G256V2,
DType::MQ2G256V2,
DType::MQ4CG256,
];
for dt in v2 {
for arch in ["gfx1100", "gfx1151"] {
// MQ4CG256 is gfx12-only by intent in BOTH callers.
if dt == DType::MQ4CG256 {
assert!(
!is_batchable_la(dt, arch),
"qwen35 must refuse {dt:?} on {arch}"
);
} else {
assert!(
is_batchable_la(dt, arch),
"qwen35 should admit {dt:?} on {arch}"
);
}
assert!(
!llama::is_batchable_la(dt, arch),
"llama must refuse {dt:?} on {arch}"
);
}
assert!(
is_batchable_la(dt, "gfx1201"),
"qwen35 should admit {dt:?} on gfx1201"
);
assert!(
!llama::is_batchable_la(dt, "gfx1201"),
"llama must refuse {dt:?} on gfx1201"
);
for arch in ["gfx1030", "gfx1010"] {
assert!(
!is_batchable_la(dt, arch),
"qwen35 must refuse {dt:?} on {arch}"
);
assert!(
!llama::is_batchable_la(dt, arch),
"llama must refuse {dt:?} on {arch}"
);
}
}
// Absolute pins so the test also fails if the shared rule itself
// regresses, not just on caller drift.
assert!(is_batchable_la(DType::MQ4G256V2, "gfx1201"));
assert!(!is_batchable_la(DType::MQ4G256V2, "gfx1030"));
assert!(!is_batchable_la(DType::MQ4CG256, "gfx1100"));
assert!(!llama::is_batchable_la(DType::MQ4G256V2, "gfx1201"));
}

#[test]
fn qwen35_v2_dense_keys_are_exact_no_hfq4_default() {
// Contract: every admitted V2 dtype maps 1:1 to its exact V2 kernel
Expand Down
1 change: 1 addition & 0 deletions crates/hipfire-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ http-body-util = "0.1"
hyper = { version = "1", features = ["http1", "server"] }
hyper-util = { version = "0.1", features = ["tokio"] }
libc = "0.2"
md5 = "0.8"
hipfire-config = { path = "../hipfire-config" }
hipfire-client = { path = "../hipfire-client" }
hipfire-registry = { path = "../hipfire-registry" }
Expand Down
8 changes: 4 additions & 4 deletions crates/hipfire-cli/map.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@ _Generated by `scripts/check-crate-maps.py` from the tree — do not edit inside
| File | Lines | Public items | Tests |
|---|---:|---:|---:|
| [`src/bench_concurrency.rs`](src/bench_concurrency.rs) | 720 | 21 | 9 |
| [`src/main.rs`](src/main.rs) | 9,692 | 0 | 65 |
| [`src/main.rs`](src/main.rs) | 10,762 | 0 | 87 |
| [`src/serve/complete.rs`](src/serve/complete.rs) | 6,754 | 0 | 89 |
| [`src/serve/http.rs`](src/serve/http.rs) | 1,089 | 0 | 6 |
| [`src/serve/metrics.rs`](src/serve/metrics.rs) | 328 | 0 | 5 |
| [`src/serve/mod.rs`](src/serve/mod.rs) | 2,116 | 2 | 16 |
| [`src/serve/mod.rs`](src/serve/mod.rs) | 2,127 | 2 | 16 |
| [`src/setup.rs`](src/setup.rs) | 1,529 | 0 | 16 |

### Public API surface
Expand All @@ -43,7 +43,7 @@ _Generated by `scripts/check-crate-maps.py` from the tree — do not edit inside
### Dependencies (from `Cargo.toml`)

- path: `hipfire-client`, `hipfire-config`, `hipfire-registry`, `hipfire-runtime`, `saddle-core`
- external: `anyhow`, `bytes`, `clap`, `ctrlc`, `http-body-util`, `hyper`, `hyper-util`, `libc`, `serde`, `serde_json`, `sha2`, `tokio`, `tokio-util`, `ureq`
- external: `anyhow`, `bytes`, `clap`, `ctrlc`, `http-body-util`, `hyper`, `hyper-util`, `libc`, `md5`, `serde`, `serde_json`, `sha2`, `tokio`, `tokio-util`, `ureq`
- dev: —
- build: —

Expand All @@ -53,6 +53,6 @@ _Generated by `scripts/check-crate-maps.py` from the tree — do not edit inside

### Totals

- 7 modules · 22,228 lines · 23 public items · 206 tests · 0 examples
- 7 modules · 23,309 lines · 23 public items · 228 tests · 0 examples

<!-- crate-map:generated:end -->
Loading
Loading