CP HiCache trace: cross-rank loc-divergence confirm (visible_locs_hash + victim_set + release_draw)

The decisive level-1 instrumentation for the cross-rank logical-loc
divergence hypothesis. Prior traces all keyed PER-RANK (host pools aren't
comparable across ranks) -- which structurally hid the one invariant that
matters: the visible LOGICAL-loc sequence for a reloaded node must be
bit-identical on every CP rank, or the cross-rank gather reads token j from
its owner rank at a slot that rank filled with a different token.

- visible_locs_hash (cache_controller.load_cp): per-node, per-rank khash of
  the visible logical locs, emitted for EVERY node incl. zero-owned so the
  analyzer can diff across ranks by node_id. Divergence = root cause.
- victim_set (hiradix _evict_cp_load_back_owner_lanes): per-rank device
  load-back eviction victim ids. Device eviction is keyed on wall-clock
  last_access_time (per-rank, NOT replicated -- unlike host eviction's
  deterministic (priority, node.id)); divergent victims is the trigger.
- release_draw (allocator.alloc_pages_with_owners): fires when a lane's free
  bucket is exhausted and the deferred-free release bucket is tapped -- the
  use-after-free/aliasing secondary.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-17 08:29:54 +00:00
parent 1d54b0b7ab
commit 25c2d6d606
3 changed files with 53 additions and 0 deletions

View File

@@ -1705,6 +1705,26 @@ class HiCacheController:
node_device_indices = device_indices[offset : offset + padded_len]
offset += padded_len
visible_chunks.append(node_device_indices[:valid_len])
if trace_enabled(1):
# CROSS-RANK invariant: the visible logical-loc sequence for this
# node MUST be byte-identical on every CP rank — the cross-rank
# gather reads token j from its owner rank at physical(loc_j), so
# if rank A and rank R disagree on loc_j, A reads R's slot for a
# DIFFERENT token (right bytes, wrong place). Emitted for EVERY
# node (incl. zero-owned, before the continue below) so the
# analyzer can diff this hash across ranks by node_id. Divergence
# here is produced by wall-clock-LRU device eviction giving ranks
# different free buckets in alloc_pages_with_owners.
_vis = node_device_indices[:valid_len]
cptrace(
1,
"visible_locs_hash",
node_id=getattr(node, "id", -1),
cprank=self.cp_shared_kv_layout.cp_rank,
n=int(_vis.numel()),
locs_hash=khash(_vis),
locs=rng(_vis),
)
if self.has_draft_hicache:
draft_host_indices = getattr(
meta, "draft_host_indices", None

View File

@@ -1093,6 +1093,20 @@ class CPSharedPagedTokenToKVPoolAllocator(PagedTokenToKVPoolAllocator):
page_size, dtype=torch.int64, device=self.device
).unsqueeze(0)
out_indices = (base + offsets).reshape(-1)
if trace_enabled(1) and any(c > 0 for c in selected_release_counts):
# Tapped the DEFERRED-FREE (release) bucket because a lane's free
# bucket was exhausted — only under eviction pressure. A release page
# may still be read by an in-flight kernel (deferred free exists to
# prevent exactly this), so handing it to an H2D reload here is a
# use-after-free / aliasing risk the byte-round-trip hash can't see.
cptrace(
1,
"release_draw",
cprank=self.cp_rank,
pages=len(page_compute_owners),
free_by_owner=selected_free_counts,
release_by_owner=selected_release_counts,
)
self._consume_owner_bucket_prefix(
release=False, counts_by_owner=selected_free_counts
)

View File

@@ -1310,6 +1310,25 @@ class HiRadixCache(RadixCache):
) -> CpLoadBackPlan:
evict_start_time = time.perf_counter()
eviction_plan = self._plan_cp_load_back_owner_lane_evictions(plan)
if trace_enabled(1):
# ROOT-CAUSE signal: device load-back eviction victim selection is
# keyed on wall-clock last_access_time (per-rank monotonic clock, NOT
# replicated across CP ranks — unlike host eviction which uses the
# deterministic (priority, node.id)). So ranks can pick DIFFERENT
# victims -> free DIFFERENT pages -> diverge alloc_pages_with_owners
# -> req_to_token disagrees across ranks. Log the victim id set per
# rank for this load op; the analyzer diffs it across ranks. A
# cross-rank mismatch confirms the divergence trigger.
cptrace(
1,
"victim_set",
node_id=node_id,
cprank=self._cp_hicache_cp_rank(),
nvictims=len(eviction_plan.victims),
victims=sorted(
int(getattr(v, "id", -1)) for v in eviction_plan.victims
),
)
plan_elapsed_ms = (time.perf_counter() - evict_start_time) * 1000.0
if plan_elapsed_ms >= 1000.0:
logger.warning(