Skip to content

fix(VT-REFTIER-HOST-ADDRESSABLE): the reference tier gated on unified memory, not on whether the host can address it (#844, #1435) - #1477

Merged
localai-bot merged 6 commits into
mainfrom
row/VT-REFTIER-HOST-ADDRESSABLE
Aug 20, 2026
Merged

fix(VT-REFTIER-HOST-ADDRESSABLE): the reference tier gated on unified memory, not on whether the host can address it (#844, #1435)#1477
localai-bot merged 6 commits into
mainfrom
row/VT-REFTIER-HOST-ADDRESSABLE

Conversation

@localai-bot

@localai-bot localai-bot commented Aug 20, 2026

Copy link
Copy Markdown
Collaborator

ReferenceTierEligible decides whether a device may receive the portable CPU
reference tier. It asked Backend::UnifiedMemory(). A host kernel does not need
unified memory; it needs to be able to dereference what Backend::Alloc
returned. include/vt/backend.h already carried the refutation, beside the
predicate that asks the right question:

CUDA on GB10 reports unified memory because host and device address the same
physical RAM, yet a plain cudaMalloc pointer is still not
host-dereferenceable.

Default false: a backend must OPT IN, because being wrong here hands a device
pointer to a host memcpy and segfaults.

CudaBackend::Alloc calls cudaMalloc. So every CUDA op without a native
kernel installed the CPU host kernel as a vt-cpu-ref provider, that kernel
dereferenced device pointers, and the process took SIGSEGV — after printing a
banner that claimed the opposite:

[vt reference-tier] op=MatmulFp8BlockScaled device=cuda has NO native kernel;
                    running the PORTABLE CPU fallback (correct but slow)

This is #844, measured twice on GB10: vt::QuantFp8Static on sm_110 (#960),
and vt::MatmulFp8BlockScaled on a CUTLASS-less CUDA build (#1435), where
tests/vt/test_ops_matmul_fp8_block_cuda exits 139 with
test cases: 0 assertions: 0. The second is reachable on a default build:
VLLM_CPP_CUTLASS_FETCH defaults OFF and CUTLASS is not a submodule.

Why this got a row and a spec, and not an in-flow fix

The reference tier is shared dispatch. Every op that can fall back, on every
backend, resolves through this one predicate, so the blast radius is the whole
op table rather than one FP8 kernel. .agents/issue-index.md had already
recorded the same judgement on #1435 — "both are code changes on a CUDA path
needing their own row, spec and hardware re-gate" — and
.agents/specs/vt-fp8-quant-arch-gate.md ## Outcome recorded that #960
deliberately did not take this on: "making the reference tier refuse ... is
#844's class, which is a larger change to the tier and is deliberately still
open".

So: row VT-REFTIER-HOST-ADDRESSABLE, spec
.agents/specs/vt-reference-tier-host-addressable.md,
committed in 447cb5c9e before the implementation in 817e1769c. The commit
order is the proof. The row is deliberately not added to an area matrix:
BACKEND-ACCEL-PROVIDER already carries an ACTIVE row for this seam, and a
second row would put a shared-file edit in the path of a one-predicate fix.

The change

ReferenceTierEligible asks Backend::DeviceMemoryIsHostAddressable(). No new
seam, no new virtual, and no DeviceType branch — the audit's rule that
eligibility never keys on the device type is kept.

Two backend cells move, and the spec enumerates all five to show which:

Backend Alloc unified host addressable tier before tier after
CPU host true the tier's source, never a target no no
CUDA cudaMalloc true on GB10 false yes no
Vulkan host-visible, host-coherent, persistently mapped true only where a combined host-visible, host-coherent, DEVICE_LOCAL type exists true, unconditionally, already overridden yes, except where unified is false yes, always
Metal MTLResourceStorageModeShared hasUnifiedMemory true, once it answers yes yes
ROCm managed when integrated, else hipMalloc see below equal to unified yes yes

CUDA loses the tier — that is the crash. Vulkan widens, and the first draft
of this description got that wrong by claiming only one cell moved.
VulkanBackend::DeviceMemoryIsHostAddressable() already returned true
unconditionally, while UnifiedMemory() reads VulkanContext::unified_memory(),
which is set from
FindMemoryType(mem, ~0u, kHostFlags | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) >= 0.
Where no such combined type exists that is false, the context falls back to
FindMemoryType(mem, ~0u, kHostFlags) and then VT_CHECKs that one was found.
So on that device every allocation is host-visible and host-coherent anyway, and
a tier that used to be withheld is now installed. Sound because of that
VT_CHECK, not because a portable tier is harmless.

Metal and ROCm gain a one-line override so they do not lose the tier as a side
effect. Both return the value those backends already report for unified memory,
so their behaviour is byte-identical. ROCm answers unified_memory_ rather than
managed_alloc_ on purpose: the registrar sets
unified_memory_ = managed_alloc || (pageable_memory_access && integrated), and
both branches give the host a pointer it may dereference — the first by the
hipMallocManaged contract, the second by the PageableMemoryAccess attribute
that the backend's own comment records as measured on gfx1151 and gfx1103.

Two messages change with it. The refusal names which precondition the device
failed, so a reader does not have to open op_provider.cpp to learn that a
portable fallback exists and was withheld. The banner names the fact that makes
it valid instead of asserting correctness in three words — those three words are
what #844 quotes as having misled a reader past a
SIGSEGV.

Red first, then green

The condition is reproducible with no GPU: it is a property pair on a backend,
not a hardware event. tests/vt/test_reference_tier.cpp gains a fake backend
that reports UnifiedMemory() == true and
DeviceMemoryIsHostAddressable() == false — the GB10 CUDA shape — on its own
device slot, because a reference-tier provider cannot be uninstalled once
registered and the case must observe an empty table. That slot is skipped, not
asserted empty
; see the review repairs below for why that distinction was a
must-fix.

RED, on the unfixed tree at 447cb5c9e (ANSI stripped, both lines read):

test cases:  6 |  5 passed | 1 failed | 0 skipped
assertions: 34 | 26 passed | 8 failed |
Status: FAILURE!            TEST_RC=1

Failing for the intended reason, not an incidental one:

ERROR: CHECK_FALSE( vt::ReferenceTierEligible(kSlot) ) is NOT correct!
  values: CHECK_FALSE( true )
ERROR: CHECK( vt::RegisterReferenceTier(kSlot) == 0 ) is NOT correct!
  values: CHECK( 107 == 0 )
ERROR: CHECK( thrown_fn != vt::GetOp(OpId::kRelu, DeviceType::kCPU) ) is NOT correct!
  values: CHECK( 1 != 1 )

107 host kernels installed for a device the host cannot address, and GetOp
returned the CPU function pointer rather than throwing. That last assertion is
what separates a refusal from a fallback: the tier installs src->fn, the very
same pointer, so an equal answer is the defect even when nothing throws.

GREEN, at 817e1769c:

test cases:  6 |  6 passed | 0 failed | 0 skipped
assertions: 34 | 34 passed | 0 failed |
Status: SUCCESS!            TEST_RC=0

The rest of the suite

Full CPU build clean (-Werror, 1130/1130, BUILD_RC=0, zero error: lines),
then ctest -j 6 over the whole tree:

99% tests passed, 1 tests failed out of 574
The following tests FAILED:
	309 - test_engine_core_proc (Failed)

That one is #1052, which the issue index already records at this exact
assertion — tests/vllm/v1/test_engine_core_proc.cpp:481 "searches for the abort
frame over a FIXED bud[get]" and needs the parallel harness to reproduce. It is
not reachable from this change: grep -c 'UnifiedMemory\|RegisterBackend\|ReferenceTier'
over that test file is 0, so it registers no backend, and on a CPU-only
build TryGetBackend returns nullptr for every non-CPU device, which makes the
old and new predicates return identically false. Rerun standalone three times
here: SUCCESS, FAILURE, SUCCESS, with assertion counts of 109, 1104 and
116 — a race, not a verdict. Another session was running its own ctest on this
box at the same time.

The seam's own suites, run together afterwards: test_reference_tier,
test_op_provider, test_backend_cross_device (4 variants),
test_backend_multidevice — 7/7 passed.

Mutation

The fix mutated in a scratch copy — the predicate put back to UnifiedMemory(),
one line:

$ diff -u op_provider.cpp.orig src/vt/op_provider.cpp
-  return b != nullptr && b->DeviceMemoryIsHostAddressable();
+  return b != nullptr && b->UnifiedMemory();
 1 file changed, 1 insertion(+), 1 deletion(-)

MUT_BUILD_RC=0        compile_err: (none)
MUT_TEST_RC=1
test cases:  6 |  5 passed | 1 failed | 0 skipped
assertions: 34 | 26 passed | 8 failed |
Status: FAILURE!

Both the diffstat and the compile result are printed because a mutation that
never applied and a mutation that failed to build each read as a passing test.
The tree was then restored and re-verified byte-for-byte:
sha256 e9ad9fd6e69124153b9bd34a2993c05f5442acaa8a507cb9437e0a463d711a39 before
and after, green again at 6/6 and 34/34.

The one .cu file, compiled by a real nvcc

src/vt/cuda/cuda_attention_cross.cu carried a header note whose premise this
change removes: it said GB10 would have run the DiT's cross-attention on the
host, "running, correct, and making 'the forward ran on the GPU' false". It was
never correct — the host kernel dereferences device pointers — and after this
change it is not possible. The edit is comment-only.

Comment-only is not a licence to skip nvcc here, so it did not:
rc run -d thor:gpu0, job 645bf395-23fc-408f-a9ad-b9823885622c, NVIDIA Thor,
CUDA 13.0 V13.0.88, aarch64. Configure with -DVLLM_CPP_CUDA=ON -DVLLM_CPP_CUDA_ARCHITECTURES=121a and no CUTLASS, then the single object:

[1/1] Building CUDA object CMakeFiles/vllm.dir/src/vt/cuda/cuda_attention_cross.cu.o
NVCC_TU_RC=0
object bytes: 162576
ELF file    1: cuda_attention_cross.cu.1.sm_121a.cubin
RESULT=PASS

The postcondition is asserted, not inferred from rc=0: the object exists and
carries sm_121a SASS.

A second, unplanned measurement

That same configure printed, on a build containing no CUTLASS at all:

--   CUDA feature cutlass-nvfp4: ENABLED for [121a]
--   CUDA feature cutlass-fp8: ENABLED for [121a]

#1435 measured that on dgx:gpu0 for one feature cell. A second box and a
second cell make it a property of vt_cuda_report_feature reading the
architecture intersection before the CUTLASS detection, not a property of either
host. Recorded in ## Owed by 7c07270b6, where that half of #1435 lives.

Fresh review: five findings, all repaired in b2c29e8f9

F1, and it was a must-fix. The new case took kTENSTORRENT believing the
enumerator was unused. It is not: src/vt/tenstorrent/tenstorrent_ops.cpp
registers 21 op sites on it, OpId::kRelu among them, and vllm carries an
INTERFACE --whole-archive, so on -DVLLM_CPP_TENSTORRENT=ON that registrar
runs inside this test binary. The old REQUIRE(OpProviderCount(kRelu, kSlot) == 0)
was commented as failing loudly if something were wrong. Nothing has to be wrong:
it fails unconditionally on a supported configuration no CI lane builds, so it
would have landed as a permanent red for whoever next enabled that backend, and
RegisterBackend would have displaced a live backend on the way.

Verified here both ways, with a scratch static registrar reproducing what
--whole-archive does:

(a) pre-guard code + simulated Tenstorrent registrar
    FATAL ERROR: REQUIRE( vt::OpProviderCount(OpId::kRelu, kSlot) == 0 )
    test cases:  6 |  5 passed | 1 failed        BUILD_RC=0  compile_err: none
    assertions: 23 | 22 passed | 1 failed        git diff --stat: 12 insertions(+)
    Status: FAILURE!                             TEST_RC=1

(b) guarded code + the SAME simulated registrar
    MESSAGE: SKIP: DeviceType::kTENSTORRENT carries a backend or providers ...
    test cases:  6 |  6 passed | 0 failed        BUILD_RC=0  compile_err: none
    assertions: 22 | 22 passed | 0 failed        git diff --stat: 32 insertions(+)
    Status: SUCCESS!                             TEST_RC=0

(a) reproduces the reviewer's numbers exactly. The tree was restored
byte-for-byte afterwards (sha256 0735aeb9…f02741b) and rebuilt green. The slot
itself stays: kXPU is the only DeviceType with no production registration and
this case cannot share it, because a reference-tier provider cannot be
uninstalled once registered. What was missing was the guard, not a different
slot.

F2. include/vt/backend.h still described the tier as reading
UnifiedMemory(), at the FlushPending() comment and at TryGetBackend. That
is the header a reader opens for exactly this distinction.

F3. "Exactly one cell moves" was wrong; corrected above, in the spec's
Design table and Risks item 1, and in the comment in op_provider.cpp.

F4. Split the remainder of #844 into #1482 rather than leaving it owned by an
issue this PR closes. Reasoning under Issues below.

F5. Three Mamba2 guards justified themselves with "ReferenceTierEligible(kCUDA)
is TRUE … GetOp does not throw". Both halves are now false. The guards are
worth keeping — they still catch a run-time decline, and a future backend
answering the narrow predicate true restores the hazard exactly — so each
paragraph now reads as the reason the guard exists, and says not to delete it.
Comment-only; suites unchanged and green:
test_ops_mamba2_ssd 8/8 · 1175 assertions, test_ops_mamba2_state_update 6/6 ·
2469, test_ops_mamba2_gated_norm 9/9 · 2107.

Reachability, run by the reviewer and not by me. Deleting the refusal clause
from the VT_CHECK inside Resolve — the production path every vt::GetOp
takes — reds test_reference_tier.cpp. So the new message is measured through a
production entry point, not by calling the helper directly. Recorded in the
spec's gates, because "nothing lands dead" asks for exactly this.

Focused suite after the repairs: 6 cases, 6 passed, 33 assertions, 33 passed,
Status: SUCCESS!
— one assertion fewer than the 34 quoted above, because the
precondition REQUIRE became the skip guard. Seam suites re-run together: 8/8.

What this does NOT claim

Nothing about the block-wise FP8 arm. It has no token gate, no speed claim,
and its correctness is established only on the seven shapes actually run under
#1437. This change turns one crash into one named refusal and claims nothing
else about that arm.

No CUDA run. The defect was measured on GB10 and the fix is verified on the
host tier against a fake backend carrying the exact property pair. A CUDA re-run
of tests/vt/test_ops_matmul_fp8_block_cuda on a CUTLASS-less build, to record
the refusal replacing exit 139, is owed by this row and named in the spec.

Metal and ROCm are not compiled anywhere this change can reach. CI has no
macOS or ROCm job and this host has neither toolchain. That is why each override
is one line, placed beside the existing UnifiedMemory() override in the same
class, returning a value those backends already compute.

Issues

Fixes #844.

#1435 stays OPEN, deliberately. Its vt_cuda_report_feature half needs a CUDA
configure and is listed under ## Owed in this row's spec, with the thor
reproduction above.

#1482 is new, and it is why Fixes #844 is safe. Two of #844's four "what done
looks like" items are not done here: item 1 also wants the refusal to name the
BUILD FEATURE that would have supplied the kernel (the landed message names the
op, the device and the failed precondition, not this build has no cutlass-fp8), and item 4 wants a warning at engine construction rather than
only at configure time. The spec originally named #844 itself as the owner of
that remainder, which would have pointed at a closed issue the moment this
merged. #1482 carries it, owned by this row, indexed, and referenced from
## Owed.

That sentence and the one above are worded to keep a closing keyword away from
every number except 844: PR #1155 auto-closed issue #584 from inside ordinary
prose.

NOTE ON THE MERGE. docs/USAGE.md is absent from this change's file list.
It carried the same misleading guidance and was going to be corrected here,
but #1491 RETIRED that section outright rather than relocating it -- its
migration manifest routes it to docs/BUILD.md as deduplicated, and no
prose matching correct but slow, portable CPU fallback or NO native kernel survives anywhere under docs/. Re-applying the edit would have
resurrected deleted content, so the file resolves to origin/main byte for
byte and the debt is discharged by the deletion.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]

mudler added 5 commits August 20, 2026 15:56
…mory is unified, not whether the host can address it (#844, #1435)

`ReferenceTierEligible` decides whether a device may receive the portable CPU
reference tier, and it asks `Backend::UnifiedMemory()`. A host kernel does not
need unified memory; it needs to be able to dereference what `Backend::Alloc`
returned. `include/vt/backend.h` already records the difference beside
`Backend::DeviceMemoryIsHostAddressable()`: CUDA on GB10 reports unified memory
because host and device address the same physical RAM, and a plain `cudaMalloc`
pointer is still not host-dereferenceable.

So on GB10 every op with no native CUDA kernel installed the CPU host kernel,
which then dereferenced device pointers. The process took SIGSEGV under a banner
claiming a "correct but slow" fallback. Measured twice: `vt::QuantFp8Static` on
sm_110 (#960), and `vt::MatmulFp8BlockScaled` on a CUTLASS-less CUDA build
(#1435), which exits 139 with `test cases: 0  assertions: 0`.

This commit is the spec only, committed before the implementation so the commit
order proves the order of work. It argues the predicate swap, enumerates all
five backends and shows that exactly one cell moves, rejects a copy-in/copy-out
staging tier with reasons, and records the `vt_cuda_report_feature` half of
#1435 under `## Owed` because it needs a CUDA configure this host cannot run.

The issue index gains a row for #844, which had none.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
… the host cannot address, instead of segfaulting on it (#844, #1435)

`ReferenceTierEligible` now asks `Backend::DeviceMemoryIsHostAddressable()`
instead of `Backend::UnifiedMemory()`. A CPU kernel dereferences the pointers
`Backend::Alloc` returned, so host-addressability is the question it asks;
unified memory is a wider property that does not imply it. `include/vt/backend.h`
already carried the refutation beside the narrow predicate, and its default is
`false` for exactly this reason.

CUDA allocates with `cudaMalloc` and reports unified memory on GB10, so it used
to be eligible. Every CUDA op without a native kernel therefore installed the CPU
host kernel over device pointers, and the process took SIGSEGV under a banner
claiming a correct fallback. It now refuses by name, and the refusal says which
precondition the device failed. The banner names the property that permits it
rather than asserting correctness in three words.

Exactly one backend cell moves. Vulkan already overrides the narrow predicate;
Metal (MTLResourceStorageModeShared) and ROCm (managed or pageable-access
integrated allocations) gain a one-line override that returns the value they
already report for unified memory, so both keep the tier and neither changes
behaviour. Neither translation unit is compiled by CI or by this host, which is
why each override is one line beside the existing `UnifiedMemory()` override in
the same class.

`tests/vt/test_reference_tier.cpp` reproduces the GB10 property pair without a
GPU: a fake backend that reports unified memory and refuses host-addressability.
The case requires that no provider installs, that `GetOp` throws rather than
returning the CPU function pointer, and that the message names the op, the
device and the reason. On the unfixed tree the tier installs 107 providers and
`GetOp` returns the host kernel.

`src/vt/cuda/cuda_attention_cross.cu` carried a header note whose premise this
change removes: it said GB10 would have run the DiT's cross-attention on the
host, "running, correct". That was never correct, and it is no longer possible.
Comment only; the translation unit's code is untouched.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
…rt is not one box and not one feature cell

The `nvcc` compile check this row owed for its one comment-only `.cu` edit ran on
`thor:gpu0` (NVIDIA Thor, CUDA 13.0 V13.0.88, aarch64), job
`645bf395-23fc-408f-a9ad-b9823885622c`. It configured this branch at `817e1769c`
with `-DVLLM_CPP_CUDA=ON -DVLLM_CPP_CUDA_ARCHITECTURES=121a` and no CUTLASS, and
the configure reported `cutlass-nvfp4: ENABLED for [121a]` and
`cutlass-fp8: ENABLED for [121a]`.

#1435 measured that on `dgx:gpu0` for one feature cell. A second box and a
second cell say the same thing, so the report is a property of
`vt_cuda_report_feature` reading the architecture intersection before the
CUTLASS detection, not a property of either host. Recorded under `## Owed`,
where that half of #1435 already lives.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
…ich property the gate reads

The header of `tests/vt/test_reference_tier.cpp` states the three properties the
file proves, and property 1 still named `Backend::UnifiedMemory()` as the safety
gate. The gate now reads `Backend::DeviceMemoryIsHostAddressable()`, and the file
asserts it against two fakes rather than one: the discrete backend it always
had, and the GB10 pair added by this row.

The header also now says why the new case uses its own device slot. A
reference-tier provider cannot be uninstalled once registered, so a case that
must observe an EMPTY provider table needs a table no other case has touched.

Comment only. Rebuilt and rerun: 6 cases, 6 passed, 34 assertions, 34 passed,
`Status: SUCCESS!`.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
…rent already owns, and "exactly one cell moves" was wrong

Five review findings, one of them a guaranteed red on a legitimate build.

F1. `tests/vt/test_reference_tier.cpp` needed a device slot no other registrar
had claimed, and took `kTENSTORRENT` on the belief that the enumerator was
unused. It is not: `src/vt/tenstorrent/tenstorrent_ops.cpp` registers 21 op sites
on it, `OpId::kRelu` among them, and `vllm` carries an INTERFACE
`--whole-archive`, so on `-DVLLM_CPP_TENSTORRENT=ON` that registrar runs inside
this test binary. The old `REQUIRE(OpProviderCount(kRelu, kSlot) == 0)` was
described in a comment as failing loudly if something were wrong. Nothing has to
be wrong: it fails unconditionally on a supported configuration no CI lane
builds, so it would have landed as a permanent red for whoever next turned that
backend on, and `RegisterBackend` would have displaced a live backend on the way.

Measured both ways here, with a scratch registrar reproducing what
`--whole-archive` does. Before the guard: `6 cases | 1 failed`,
`23 assertions | 1 failed`, `FAILURE!`, rc=1 — the same numbers the reviewer got.
After the guard, same simulation: `6 cases | 6 passed`, `22 assertions`,
`SUCCESS!`, rc=0, with the skip MESSAGE printed. `kXPU` is the only slot with no
production registration and this case cannot share it, because a reference-tier
provider cannot be uninstalled once registered. So the slot stays and the guard
is what was missing.

F2. `include/vt/backend.h` still described the tier as reading `UnifiedMemory()`
in two places. That is the header a reader opens for exactly this distinction, so
a stale sentence there is the defect this row exists to remove.

F3. "Exactly one cell moves" was wrong. Vulkan moves too. Its
`DeviceMemoryIsHostAddressable()` is unconditionally `true`, while its
`UnifiedMemory()` is false where no combined host-visible, host-coherent,
DEVICE_LOCAL memory type exists — `VulkanContext` then falls back to the host
flags alone and `VT_CHECK`s that one was found. On such a device the tier was
withheld before and is installed now. It is a widening, and it is sound because
that `VT_CHECK` guarantees every allocation is host memory, not because a tier is
harmless. The spec's Design table, its Risks item 1, and the comment in
`op_provider.cpp` all said otherwise.

F4. The pull request carries `Fixes #844`, which closes it, but two of that
issue's four items are not done: the refusal names the op, the device and the
failed precondition, not the BUILD FEATURE that would have supplied the kernel,
and nothing warns at engine construction. The spec named #844 itself as owner of
that remainder, so on close the pointer would have resolved to a closed issue and
the work would be ownerless. Split into #1482, owned by this row, appended to the
issue index, and referenced from `## Owed`. `Refs #844` with the issue left open
was the alternative and is rejected: the defect in its title is fixed, and
leaving it open would misreport that.

F5. Three Mamba2 guards justified themselves with "`ReferenceTierEligible(kCUDA)`
is TRUE ... `GetOp` does not throw". Both halves are now false. The guards are
worth keeping — they still catch a run-time decline, and a future backend
answering the narrow predicate true restores the hazard exactly — so each
paragraph now reads as the reason the guard exists rather than as current
behaviour, and says not to delete it.

The spec also records the reachability mutation the reviewer ran and the
implementer did not: deleting the refusal clause from the `VT_CHECK` inside
`Resolve` reds `test_reference_tier.cpp`, so the new message is measured through
`vt::GetOp` rather than by calling the helper.

Focused suite after the repairs: 6 cases, 6 passed, 33 assertions, 33 passed,
`SUCCESS!`. One assertion fewer than before, because the precondition REQUIRE
became the skip guard.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
`origin/main` advanced to `af25bd251` while this row held a full CI verdict at
`b2c29e8f9`. Merge rather than rebase, so the reviewed SHAs and the verdict
taken on them stay reachable.

Three files are shared, and only one conflicted.

`src/vt/op_provider.cpp` auto-merged, and the two changes are disjoint. #1497
added `kDflash2SelectorEdges` and `kTopKValuesIndices` to `OpNameImpl`; this row
rewrites `ReferenceTierEligible`, adds `ReferenceTierRefusalReason`, and rewords
the reference-tier banner. The merged file was reconstructed independently, by
applying this row's diff to `origin/main`'s version, and is byte-identical to
what git produced. Neither change weakens the other: the corrected predicate has
exactly two call sites, `MaybeInstallReferenceTier` and `RegisterReferenceTier`,
and #1497 adds no third. Both of its new ops register a native CUDA kernel
(`cuda_ops.cu`, `cuda_sample.cu`), so neither reaches the reference tier on CUDA
and the narrowed gate does not change their behaviour.

`docs/USAGE.md` conflicted, and resolves to `origin/main`'s version byte for
byte. This row edited the reference-tier paragraph inside `### A DISABLED
feature removes its kernels, not the ops that do not need it`. #1491 retired
that whole section: its migration manifest routes `docs/USAGE.md:168` to
`docs/BUILD.md` as `deduplicated`, and `docs/BUILD.md` carries none of the
prose, so the subject is retired from public documentation rather than moved.
Re-applying the edit would resurrect a section a landed change deliberately
removed. The correction this row owed that file is discharged by the deletion,
because the false guidance it repaired no longer exists anywhere in `docs/`.

`.agents/issue-index.md` union-merged. All 487 of `origin/main`'s rows are
present byte for byte, this row contributes exactly its own two, and the header
prose is identical to `origin/main`.

The spec's `Why the banner's wording changes` paragraph said `docs/USAGE.md`
quotes the three words the banner drops. The merge made that false, so the
paragraph now says which change retired the quote.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
@localai-bot
localai-bot merged commit cffe59b into main Aug 20, 2026
1 of 15 checks passed
localai-bot added a commit that referenced this pull request Aug 21, 2026
…l and integrated ROCm, and its numbers do not (#1502) (#1620)

`docs/ENVIRONMENT.md` described the lever's reach as "Vulkan today" and
closed
with "No effect on CUDA/CPU/Metal, whose backends do not advertise the
property".
Both halves stopped being true at `cffe59b02` (#1477).

That change moved `ReferenceTierEligible` off the wider
`UnifiedMemory()` onto
`Backend::DeviceMemoryIsHostAddressable()`, and added truthful overrides
so no
backend silently lost the reference tier. `MetalBackend` now answers
`MetalContext::unified_memory()` and `RocmBackend` answers its
`unified_memory_`.
The weight loader gates this lever on exactly that predicate, at both
`AdoptDeviceBytesAsHost` branches in `qwen3_5_weights.cpp`, so the lever
acts on
Apple silicon and on an integrated ROCm part.

The correction is not "add two backend names". Every number in that row
is GB10
through Vulkan, and nobody has measured the lever on either new arm. The
row read
as if the measurement covered the reach, so it now says which backends
it is
MEASURED on and which merely satisfy the predicate. CUDA and CPU are
unchanged
and still inert: neither overrides the default `false`, which
`tests/vllm/platforms/test_platform.cpp` pins for GB10, and the CPU
backend
reporting `UnifiedMemory() == true` while the narrower predicate stays
`false` is
the whole reason the two properties are separate.

Verified against the tree rather than against the issue: the three
overrides, the
two gate sites, the absent CUDA and CPU overrides, and the GB10
assertion were
each read at this head.

The measurement on Metal and on integrated ROCm stays owed. It needs an
Apple-silicon box or an integrated AMD part, which this row has not
taken, so it
is recorded under `## Owed` in the spec that widened the predicate
rather than
left to be discovered from a document that now promises less than it
did.

No checker relates a backend predicate to a prose sentence, and none can
be built
cheaply, which is why this landed as a document defect rather than a red
gate.

Fixes #1502

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]

Co-authored-by: Ettore Di Giacinto <mudler@localai.io>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The vt reference-tier fallback SEGFAULTS on device tensors instead of refusing by name, and a CUTLASS-less build reaches it silently

2 participants