From 4bea302c37705ed0079e08849d174ded2e6178c1 Mon Sep 17 00:00:00 2001 From: bcloud Date: Tue, 10 Nov 2026 20:10:36 -0400 Subject: [PATCH] hrx: a host-bound refusal names the host term, not the GTT ceiling (engine #2069) pool_budget_terms() takes the smaller of the GTT headroom and host MemAvailable, but the refusal path printed the GTT figures and advised 'free GTT or lower the reserve' regardless of which term bound the budget. A host-bound refusal therefore named the resource that was NOT the problem, and its numbers were the non-binding ones. Seen directly while reproducing engine #1926 on a self-built HRX configuration: llama-bench --list-devices registered no device and printed 'GTT total 120.0 GiB with 78.0 GiB free leaves nothing under the 104.0 GiB ceiling' - which cannot be the explanation, since 78 GiB free against a 104 GiB ceiling leaves ~62 GiB of headroom. The real cause was the old pin's argument-evaluation order bug (engine #1942, fixed by #1960), which makes the host figure read as 0. host_bound already exists on pool_budget_terms_t and already decides the wording of the open-time guardrail line; this applies the same distinction to the refusal, which is the line a person reads when nothing runs at all. Message only: no threshold, no condition and no admission decision changes. Verified with -fsyntax-only against the HRX compile command for this TU (the nested llama.cpp build's compile_commands.json), since this tree has no full HRX build under the disk floor. --- ggml/src/ggml-hrx/ggml-hrx.cpp | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/ggml/src/ggml-hrx/ggml-hrx.cpp b/ggml/src/ggml-hrx/ggml-hrx.cpp index 5aa6a9dfe9fb..b39e178ca69a 100644 --- a/ggml/src/ggml-hrx/ggml-hrx.cpp +++ b/ggml/src/ggml-hrx/ggml-hrx.cpp @@ -1655,12 +1655,31 @@ static std::unique_ptr create_registry_context() { // Nothing fits under the ceiling: refuse the device here, loudly, instead of planning a launch that can // reach the fault line (#680). Report only, do not try to be clever about it. const size_t reserve = ggml::hrx::onebit::pool_reserve_bytes(); - GGML_LOG_ERROR("ggml_hrx: %s: refusing to use the device: GTT total %.1f GiB with %.1f GiB free leaves " - "nothing under the %.1f GiB ceiling (reserve GGML_HRX_GTT_RESERVE_MB, override " - "GGML_HRX_POOL_LIMIT_MB); free GTT or lower the reserve (engine #680)\n", - device_ctx->name.c_str(), device_total / (1024.0 * 1024.0 * 1024.0), - device_free / (1024.0 * 1024.0 * 1024.0), - (device_total > reserve ? device_total - reserve : 0) / (1024.0 * 1024.0 * 1024.0)); + // engine #2069: name the term that actually bound the budget. `pool_budget_terms()` takes the smaller of the two, + // so a host-bound refusal used to print the GTT figures and advise freeing GTT - which is the wrong resource, + // and the one line a person reads when nothing runs at all. `host_bound` already decides the wording of the + // open-time guardrail line; this is the same distinction on the refusal path. + if (terms.host_bound) { + GGML_LOG_ERROR("ggml_hrx: %s: refusing to use the device: host memory is the binding term - %.1f GiB " + "available against %.1f GiB of GTT headroom (GTT total %.1f GiB, %.1f GiB free, ceiling " + "%.1f GiB); free RAM, or lower GGML_HRX_GTT_RESERVE_MB / set GGML_HRX_POOL_LIMIT_MB " + "(engine #680, #2069)\n", + device_ctx->name.c_str(), + terms.host_available == ggml::hrx::onebit::kHostUnknown + ? -1.0 + : terms.host_available / (1024.0 * 1024.0 * 1024.0), + terms.gtt_term / (1024.0 * 1024.0 * 1024.0), + device_total / (1024.0 * 1024.0 * 1024.0), + device_free / (1024.0 * 1024.0 * 1024.0), + (device_total > reserve ? device_total - reserve : 0) / (1024.0 * 1024.0 * 1024.0)); + } else { + GGML_LOG_ERROR("ggml_hrx: %s: refusing to use the device: GTT total %.1f GiB with %.1f GiB free leaves " + "nothing under the %.1f GiB ceiling (reserve GGML_HRX_GTT_RESERVE_MB, override " + "GGML_HRX_POOL_LIMIT_MB); free GTT or lower the reserve (engine #680)\n", + device_ctx->name.c_str(), device_total / (1024.0 * 1024.0 * 1024.0), + device_free / (1024.0 * 1024.0 * 1024.0), + (device_total > reserve ? device_total - reserve : 0) / (1024.0 * 1024.0 * 1024.0)); + } hrx_device_release(hrx_device); continue; }