You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[correctness] PCIe DCP A2A: signed int slot_ overflows so staging_[-1] aliases signals_/self_signal_ — eager channel writes staged attention over a peer's barrier region and null-derefs #97
Found during a source review of the v20 r12 release image voipmonitor/vllm:gilded-gnosis-v20-vllmb46c3aa-si35aebc6-fi801d57a-cu132-20260730-r12. The cited sparkinfer file comes from the composed r12 tree, which is byte-identical to public commit de04125508c75e748016493f851e6bd4513b515b (git diff de04125 r12-composed -- sparkinfer/comm/pcie/pcie_dcp_a2a.cu sparkinfer/comm/pcie/pcie_dcp_a2a.py is empty, tree clean), so permalinks use that SHA; code is quoted inline regardless. vLLM caller refs are from the composed r12 vLLM tree (base b46c3aa). Deployment: GLM-5.2 753B MoE, EXL3 3.0bpw, 4x RTX 6000 Pro (sm120), TP4 with DCP4 (release gate) / DCP2 (production turnkey), nvfp4_ds_mla KV, FULL_AND_PIECEWISE CUDA graphs.
This was first noted as §5 NEW inside a review comment on #95 and never filed on its own. This report validates it independently, confirms the core mechanism (verified by compiling the exact pattern, not by reading), and corrects the consequence: in both shipped world sizes the out-of-bounds slot also produces a guaranteed null dereference, so the failure is cross-rank barrier corruption plus a device-side illegal memory access — not purely silent corruption. Purely silent corruption is the DCP8 case.
// Staging happens inside the kernel (warp-per-row, before the start// barrier); no host staging memcpys are issued.constint slot = slot_++ % 2; // :399 (run) and :460 (all_gather_heads)
staging_[slot] is then passed by value into the kernel, which uses it both as the write target and as the peer read source:
slot_ is written and read nowhere else — confirmed by grep over the whole repo: only :346, :399, :460. There is no Python-side accessor in pcie_dcp_a2a.py, and no code depends on the counter being monotonic.
slot_++ is a signed increment with no wrap guard. After 2147483647 calls it overflows: formally UB, in practice wraps to INT_MIN.
The expression takes % of the pre-increment value, and C++ % truncates toward zero, so the produced slot sequence across the wrap is:
call
slot_ before
slot_++ % 2
2^31-1
2147483646
0
2^31
2147483647
1
2^31+1
-2147483648
0 (INT_MIN is even)
2^31+2
-2147483647
-1
2^31+3
-2147483646
0
2^31+4
-2147483645
-1
So the first out-of-bounds index appears on call 2147483650 and on every second call for the remaining life of the process. Slot 1 is never used again; the double buffer degenerates to {0, -1}.
4. staging_[-1] is 64 bytes below staging_[0]. Verified independently with offsetof on the exact declarations (no CUDA needed): sizeof(Signal)=133120, sizeof(RankSignals)=sizeof(RankStaging)=64, sizeof(PCIeDCPA2A)=240, offsets rank_=0, world_size_=4, signals_=8, self_signal_=72, staging_=80, output_capacity_elems_=208, lse_offset_=216, lse_capacity_=224, slot_=232. staging_[-1] therefore covers bytes 16..79, and its ptrs[] alias:
staging_[-1].ptrs[k]
byte offset
aliases
ptrs[0]
16
signals_.signals[1]
ptrs[1]
24
signals_.signals[2]
...
...
...
ptrs[6]
64
signals_.signals[7]
ptrs[7]
72
self_signal_
The report's claim (c) holds exactly: staging_[-1]is the barrier-pointer region, shifted by one slot.
Correction the original note missed.RankSignals signals_{} is value-initialized and the constructor fills only signals[0 .. world_size-1] (:355-359), so signals_.signals[world_size .. 7] are nullptr. Because the alias shifts by one, the used index range [0, world_size) of staging_[-1] contains exactly one null for any world_size < 8:
rank 0 stages into ptrs[0] = rank 1's Signal region (valid IPC pointer, real cross-rank write); then post-barrier reads ptrs[1] = nullptr → illegal address.
rank 1 stages into ptrs[1] = nullptr → illegal address in the pre-barrier write phase, so its barrier flags never post; it would have read ptrs[0] = its own Signal region as "peer 0's staged output".
DCP4 (gate):ptrs[0..2] = signals[1..3], ptrs[3] = nullptr. Ranks 0/1/2 stage over the Signal region of ranks 1/2/3 respectively; rank 3 null-writes; every rank 0..2 also null-reads ptrs[3].
DCP8 (not shipped): all eight entries are non-null (ptrs[7] = self_signal_). No fault at all — every rank writes its staged attention output over a peer's barrier flags and reads a peer's barrier flags back as attention output. Fully silent cross-rank corruption.
The cross-rank writes do not fault. signal_ptrs are the IPC slab base pointers and staging follows the signal region in the same allocation (pcie_dcp_a2a.py:279-285, _staging_layout:95-105: slab_bytes = align_up(signal_bytes) + 2*slot_bytes). A staging write is capacity-checked to <= slot_bytes from its base (.cu:371-373), so writing slot_bytes starting at the peer's slab base stays inside the peer's own allocation — it silently overwrites Signal.self_counter (2 KiB) + Signal.peer_counter (128 KiB) and runs on into staging0. The peer spinning in start_barrier (.cu:103-118) then reads corrupted flags: while (load_flag(mine) != value) either never matches (hang) or matches spuriously (barrier released before peers staged → reduction over unstaged data).
Empirically verified, not inferred. Compiling the verbatim pattern in the same class shape with the host compiler at -O3 (g++ 13.3, no -fwrapv), with the object laundered through an int64_t exactly as fptr_t does:
The emitted body is the sign-correcting signed remainder (shrl $31 / addl / andl $1 / subl), i.e. the compiler does not narrow it to & 1, and the base offset is leaq 10(%rcx,%rax,8) = byte 80, matching offsetof(staging_). The disproof attempt "UB lets the optimizer assume slot_ >= 0 and emit & 1, accidentally fixing it" therefore fails on the shipped toolchain — and it cannot succeed in general, because the object pointer arrives through reinterpret_cast<PCIeDCPA2A *>(fptr_t) (.cu:519, :600), which destroys any value-range provenance for slot_.
Reachability
Per shipped config, eager only. run()/all_gather_heads() contain no cudaStreamIsCapturing check (unlike pcie_oneshot.cu), so the increment executes on the host at capture time and the selected staging_[slot] pointer is baked into the captured kernel node's arguments. Graph replays never touch slot_. Consequently:
FULL graphs (uniform decode, capture sizes 4..64) bake 156 ops once and then replay for free — they cannot reach the overflow.
PIECEWISE passes bake zero A2A ops: attention is in splitting_ops by default (vllm/config/compilation.py:1147, splitting_ops = list(self._attention_ops)), so MLA attention — and with it both A2A calls — runs eagerly on the capture/replay stream. This eager traffic lands on the long-lived default-stream channel created at dcp_alltoall.py:134 (single_channel=False, pool.for_stream()), which is never recreated for the life of the worker.
Both ops are gated on dcp_use_b12x = dcp_b12x and num_mqa_tokens <= VLLM_DCP_A2A_MAX_TOKENS (mla_attention.py:1391-1395), with DCP_A2A_MAX_TOKENS=64 effective in both shipped paths (serve-glm52-v16.sh:21, VLLM_USE_B12X_DCP_A2A=1 at :240). Chunked-prefill-only batches (num_mqa_tokens up to 3072) take ag_rs and never touch this channel.
Net: the reachable driver is mixed prefill+decode steps under the turnkey config (8 seqs, MTP k=5 → 6..48 MQA tokens, well under the 64-token cap, dispatched PIECEWISE → eager attention). Every such step advances slot_ by 156.
Turnkey (DCP2, 8 seqs, chunked prefill): reachable. Requires only continuous uptime, no unusual input.
Release gate (DCP4, max_num_seqs=1, graph=6): effectively unreachable. With one sequence there are no mixed prefill+decode steps, so essentially all A2A-bearing decode passes are FULL-graph replays; eager A2A traffic is limited to warmup. This is a correction to the original note, which did not separate the two configs.
A process restart resets the counter, so only long-lived servers are exposed.
The corrupting code is inside the eager dcp_lse_reduce_kernel / all_gather_heads_kernel launches themselves (not inside a captured graph), so nothing about graph replay masks or delays it.
Severity
correctness — silent cross-rank memory corruption, followed by an unrecoverable crash or hang. Ranks 0..W-2 write staged attention data straight into a peer's barrier-flag arrays across the IPC mapping; rank W-1 dereferences a null device pointer. On the shipped DCP2/DCP4 the crash is guaranteed and roughly concurrent with the corruption (illegal address → sticky CUDA error → engine death; or a permanent spin in start_barrier on smashed flags). At DCP8 there is no fault, so it degrades to purely silent wrong attention output on every second op forever. It is a slow-fuse bug — nothing is observable until it isn't — but the fuse is uptime, not a rare input, and the corruption crosses the rank boundary, so it can also manifest as an unexplained peer hang rather than a local error.
The original note quoted "~1.6 days at 100 eager passes/s"; 100 eager forward passes/s is not plausible for a 753B MoE on 4x sm120, and only the mixed fraction of steps counts. A realistic turnkey band is ~4–40 days of continuous serving, i.e. weeks, not hours — still comfortably inside the lifetime of a production deployment that is not restarted.
Bytes corrupted per bad op: one contiguous run of batch * total_heads * head_dim * 2 bytes from the peer's slab base, plus an LSE write at +lse_offset. sizeof(Signal) = 133,120 B (130 KiB), so with total_heads = 64 a 48-token decode step writes ~3 MiB — about 24x the entire peer barrier region. Even a 16-head, 8-token step writes 128 KiB, i.e. the whole region. There is no partial-damage regime.
Suggested fix
Mirror the sibling channel in this same directory, which already gets it right — pcie_dcp_topk.cu:161-198 uses uint32_t next_slot_ = 0; with next_slot_ ^= uint32_t{1};:
This preserves today's slot sequence exactly (0,1,0,1,...), so the first-call slot and the alternation the double buffer relies on are unchanged. slot_ = (slot_ + 1) & 1 also removes the overflow but flips the phase to 1,0,1,0,...; harmless, only worth noting so it is not mistaken for a no-op. Plain unsigned slot_ with the existing slot_++ % 2 is also correct (unsigned wrap is defined, % stays in {0,1}), but keeps a pointless 32-bit counter.
Fix safety: host-side arithmetic only, so it is capture-safe (nothing new executes under capture, no host sync, no allocation), numerics-neutral (same bytes, same buffer), and ABI-neutral — the whole extension is a single JIT-compiled TU (torch.utils.cpp_extension.load, pcie_dcp_a2a.py:109-119), and slot_ is not exposed to Python. Nothing reads slot_ expecting monotonicity (only :346/:399/:460 touch it), so no caller changes. This is orthogonal to and compatible with the device-side slot derivation proposed as F1 in #95, which would remove the host counter altogether.
Same overflow pattern, out of scope here, worth a separate look: pcie_twoshot.cu:264 with const int s = slot_ % 2; slot_++; at :315/:332, and pcie_oneshot.cu:569 with int slot = dbuf_slot_ % 2; dbuf_slot_++; at :689/:767. Both take % of a signed counter and are subject to the identical wrap; the aliasing target of [-1] in those classes was not analysed in this report.
Verification / repro hint
No GPU and no 2^31-op soak needed — the interesting behavior is entirely host-side pointer selection:
Offset check (seconds): compile the Signal/RankSignals/RankStaging/PCIeDCPA2A declarations verbatim and print offsetof for every member plus reinterpret_cast<char*>(&o.staging_[0]) - 64 - base. Expect staging_ = 80 and staging_[-1] = 16 == offsetof(signals_) + 8.
Alias check (seconds): in the same program, fill signals_[k] and self_signal_ with sentinels, new the object, launder the pointer through int64_t, set slot_ = 2147483645, and call a noinline method containing the verbatim const int slot = slot_++ % 2; return staging_[slot].ptrs[rank_];. Build with -O3 and without-fwrapv. Expect the signals_[1] sentinel on the 5th call. (Done above; reproduced on g++ 13.3.)
End-to-end (optional, GPU): add a temporary test-only setter for slot_, run the existing 2-rank tests/comm/test_pcie_dcp_a2a_gpu.py::test_pcie_dcp_a2a_eager_and_cuda_graph_correctness eager loop with slot_ pre-seeded to 2147483645, and observe the illegal-memory-access on rank 1 within a handful of iterations plus mismatching output on rank 0. With the fix the loop is clean.
Nothing to measure for the fix itself — it is behaviour-preserving for all slot_ < 2^31.
Provenance of the observation
First noted as §5 — new: int slot_ overflow indexes staging_[-1] in #95 (comment) (a second-reviewer comment on #95). It was never filed as its own issue; #95's body covers a different slot_ concern (host-baked slot parity under graph replay) and does not mention the overflow. Parent issue for context: #95. Related memory-side report: #94.
Found during a source review of the v20 r12 release image
voipmonitor/vllm:gilded-gnosis-v20-vllmb46c3aa-si35aebc6-fi801d57a-cu132-20260730-r12. The cited sparkinfer file comes from the composed r12 tree, which is byte-identical to public commitde04125508c75e748016493f851e6bd4513b515b(git diff de04125 r12-composed -- sparkinfer/comm/pcie/pcie_dcp_a2a.cu sparkinfer/comm/pcie/pcie_dcp_a2a.pyis empty, tree clean), so permalinks use that SHA; code is quoted inline regardless. vLLM caller refs are from the composed r12 vLLM tree (baseb46c3aa). Deployment: GLM-5.2 753B MoE, EXL3 3.0bpw, 4x RTX 6000 Pro (sm120), TP4 with DCP4 (release gate) / DCP2 (production turnkey),nvfp4_ds_mlaKV,FULL_AND_PIECEWISECUDA graphs.This was first noted as
§5 NEWinside a review comment on #95 and never filed on its own. This report validates it independently, confirms the core mechanism (verified by compiling the exact pattern, not by reading), and corrects the consequence: in both shipped world sizes the out-of-bounds slot also produces a guaranteed null dereference, so the failure is cross-rank barrier corruption plus a device-side illegal memory access — not purely silent corruption. Purely silent corruption is the DCP8 case.Where
sparkinfer/comm/pcie/pcie_dcp_a2a.cu#L336-L346(member layout),#L399(run, i.e.lse_reduce_scatter),#L460(all_gather_heads).staging_[slot]is then passed by value into the kernel, which uses it both as the write target and as the peer read source:slot_is written and read nowhere else — confirmed by grep over the whole repo: only:346,:399,:460. There is no Python-side accessor inpcie_dcp_a2a.py, and no code depends on the counter being monotonic.Mechanism
total_heads,head_dim=512,query_head_dim=576,max_batch_sizeall match betweenmla_attention.py:1429and:1545), so oneslot_serves 2 ops per MLA layer.slot_++is a signed increment with no wrap guard. After 2147483647 calls it overflows: formally UB, in practice wraps toINT_MIN.%of the pre-increment value, and C++%truncates toward zero, so the produced slot sequence across the wrap is:slot_beforeslot_++ % 2INT_MINis even)So the first out-of-bounds index appears on call 2147483650 and on every second call for the remaining life of the process. Slot
1is never used again; the double buffer degenerates to{0, -1}.4.
staging_[-1]is 64 bytes belowstaging_[0]. Verified independently withoffsetofon the exact declarations (no CUDA needed):sizeof(Signal)=133120,sizeof(RankSignals)=sizeof(RankStaging)=64,sizeof(PCIeDCPA2A)=240, offsetsrank_=0, world_size_=4, signals_=8, self_signal_=72, staging_=80, output_capacity_elems_=208, lse_offset_=216, lse_capacity_=224, slot_=232.staging_[-1]therefore covers bytes 16..79, and itsptrs[]alias:staging_[-1].ptrs[k]ptrs[0]signals_.signals[1]ptrs[1]signals_.signals[2]ptrs[6]signals_.signals[7]ptrs[7]self_signal_The report's claim (c) holds exactly:
staging_[-1]is the barrier-pointer region, shifted by one slot.RankSignals signals_{}is value-initialized and the constructor fills onlysignals[0 .. world_size-1](:355-359), sosignals_.signals[world_size .. 7]arenullptr. Because the alias shifts by one, the used index range[0, world_size)ofstaging_[-1]contains exactly one null for anyworld_size < 8:ptrs[0] = signals[1],ptrs[1] = nullptr.ptrs[0]= rank 1's Signal region (valid IPC pointer, real cross-rank write); then post-barrier readsptrs[1]=nullptr→ illegal address.ptrs[1]=nullptr→ illegal address in the pre-barrier write phase, so its barrier flags never post; it would have readptrs[0]= its own Signal region as "peer 0's staged output".ptrs[0..2] = signals[1..3],ptrs[3] = nullptr. Ranks 0/1/2 stage over the Signal region of ranks 1/2/3 respectively; rank 3 null-writes; every rank 0..2 also null-readsptrs[3].ptrs[7] = self_signal_). No fault at all — every rank writes its staged attention output over a peer's barrier flags and reads a peer's barrier flags back as attention output. Fully silent cross-rank corruption.The cross-rank writes do not fault.
signal_ptrsare the IPC slab base pointers and staging follows the signal region in the same allocation (pcie_dcp_a2a.py:279-285,_staging_layout:95-105:slab_bytes = align_up(signal_bytes) + 2*slot_bytes). A staging write is capacity-checked to<= slot_bytesfrom its base (.cu:371-373), so writingslot_bytesstarting at the peer's slab base stays inside the peer's own allocation — it silently overwritesSignal.self_counter(2 KiB) +Signal.peer_counter(128 KiB) and runs on intostaging0. The peer spinning instart_barrier(.cu:103-118) then reads corrupted flags:while (load_flag(mine) != value)either never matches (hang) or matches spuriously (barrier released before peers staged → reduction over unstaged data).Empirically verified, not inferred. Compiling the verbatim pattern in the same class shape with the host compiler at
-O3(g++ 13.3, no-fwrapv), with the object laundered through anint64_texactly asfptr_tdoes:The emitted body is the sign-correcting signed remainder (
shrl $31 / addl / andl $1 / subl), i.e. the compiler does not narrow it to& 1, and the base offset isleaq 10(%rcx,%rax,8)= byte 80, matchingoffsetof(staging_). The disproof attempt "UB lets the optimizer assumeslot_ >= 0and emit& 1, accidentally fixing it" therefore fails on the shipped toolchain — and it cannot succeed in general, because the object pointer arrives throughreinterpret_cast<PCIeDCPA2A *>(fptr_t)(.cu:519,:600), which destroys any value-range provenance forslot_.Reachability
Per shipped config, eager only.
run()/all_gather_heads()contain nocudaStreamIsCapturingcheck (unlikepcie_oneshot.cu), so the increment executes on the host at capture time and the selectedstaging_[slot]pointer is baked into the captured kernel node's arguments. Graph replays never touchslot_. Consequently:splitting_opsby default (vllm/config/compilation.py:1147,splitting_ops = list(self._attention_ops)), so MLA attention — and with it both A2A calls — runs eagerly on the capture/replay stream. This eager traffic lands on the long-lived default-stream channel created atdcp_alltoall.py:134(single_channel=False,pool.for_stream()), which is never recreated for the life of the worker.dcp_use_b12x = dcp_b12x and num_mqa_tokens <= VLLM_DCP_A2A_MAX_TOKENS(mla_attention.py:1391-1395), withDCP_A2A_MAX_TOKENS=64effective in both shipped paths (serve-glm52-v16.sh:21,VLLM_USE_B12X_DCP_A2A=1at:240). Chunked-prefill-only batches (num_mqa_tokensup to 3072) takeag_rsand never touch this channel.Net: the reachable driver is mixed prefill+decode steps under the turnkey config (8 seqs, MTP k=5 → 6..48 MQA tokens, well under the 64-token cap, dispatched PIECEWISE → eager attention). Every such step advances
slot_by 156.max_num_seqs=1,graph=6): effectively unreachable. With one sequence there are no mixed prefill+decode steps, so essentially all A2A-bearing decode passes are FULL-graph replays; eager A2A traffic is limited to warmup. This is a correction to the original note, which did not separate the two configs.The corrupting code is inside the eager
dcp_lse_reduce_kernel/all_gather_heads_kernellaunches themselves (not inside a captured graph), so nothing about graph replay masks or delays it.Severity
correctness — silent cross-rank memory corruption, followed by an unrecoverable crash or hang. Ranks
0..W-2write staged attention data straight into a peer's barrier-flag arrays across the IPC mapping; rankW-1dereferences a null device pointer. On the shipped DCP2/DCP4 the crash is guaranteed and roughly concurrent with the corruption (illegal address → sticky CUDA error → engine death; or a permanent spin instart_barrieron smashed flags). At DCP8 there is no fault, so it degrades to purely silent wrong attention output on every second op forever. It is a slow-fuse bug — nothing is observable until it isn't — but the fuse is uptime, not a rare input, and the corruption crosses the rank boundary, so it can also manifest as an unexplained peer hang rather than a local error.Impact (recomputed independently)
all_gather_headsatmla_attention.py:1429+lse_reduce_scatterat:1545), both gated on the same flag →2 x 78 = 156for GLM-5.2 (78 decoder layers, of which 75 MoE), consistent with the count established in [correctness] DCP A2A capture channel adoption: graphs sharing one channel bake host-side staging-slot parity; stale capture stream-key mappings can hand a graph's channel to later captures #95.2147483650(= 2^31 + 2). Eager passes:2147483650 / 156 = 13,765,921.staging_[-1]The original note quoted "~1.6 days at 100 eager passes/s"; 100 eager forward passes/s is not plausible for a 753B MoE on 4x sm120, and only the mixed fraction of steps counts. A realistic turnkey band is ~4–40 days of continuous serving, i.e. weeks, not hours — still comfortably inside the lifetime of a production deployment that is not restarted.
batch * total_heads * head_dim * 2bytes from the peer's slab base, plus an LSE write at+lse_offset.sizeof(Signal) = 133,120 B (130 KiB), so withtotal_heads = 64a 48-token decode step writes ~3 MiB — about 24x the entire peer barrier region. Even a 16-head, 8-token step writes 128 KiB, i.e. the whole region. There is no partial-damage regime.Suggested fix
Mirror the sibling channel in this same directory, which already gets it right —
pcie_dcp_topk.cu:161-198usesuint32_t next_slot_ = 0;withnext_slot_ ^= uint32_t{1};:This preserves today's slot sequence exactly (
0,1,0,1,...), so the first-call slot and the alternation the double buffer relies on are unchanged.slot_ = (slot_ + 1) & 1also removes the overflow but flips the phase to1,0,1,0,...; harmless, only worth noting so it is not mistaken for a no-op. Plainunsigned slot_with the existingslot_++ % 2is also correct (unsigned wrap is defined,%stays in{0,1}), but keeps a pointless 32-bit counter.Fix safety: host-side arithmetic only, so it is capture-safe (nothing new executes under capture, no host sync, no allocation), numerics-neutral (same bytes, same buffer), and ABI-neutral — the whole extension is a single JIT-compiled TU (
torch.utils.cpp_extension.load,pcie_dcp_a2a.py:109-119), andslot_is not exposed to Python. Nothing readsslot_expecting monotonicity (only:346/:399/:460touch it), so no caller changes. This is orthogonal to and compatible with the device-side slot derivation proposed as F1 in #95, which would remove the host counter altogether.Same overflow pattern, out of scope here, worth a separate look:
pcie_twoshot.cu:264withconst int s = slot_ % 2; slot_++;at:315/:332, andpcie_oneshot.cu:569withint slot = dbuf_slot_ % 2; dbuf_slot_++;at:689/:767. Both take%of a signed counter and are subject to the identical wrap; the aliasing target of[-1]in those classes was not analysed in this report.Verification / repro hint
No GPU and no 2^31-op soak needed — the interesting behavior is entirely host-side pointer selection:
Signal/RankSignals/RankStaging/PCIeDCPA2Adeclarations verbatim and printoffsetoffor every member plusreinterpret_cast<char*>(&o.staging_[0]) - 64 - base. Expectstaging_ = 80andstaging_[-1] = 16 == offsetof(signals_) + 8.signals_[k]andself_signal_with sentinels,newthe object, launder the pointer throughint64_t, setslot_ = 2147483645, and call anoinlinemethod containing the verbatimconst int slot = slot_++ % 2; return staging_[slot].ptrs[rank_];. Build with-O3and without-fwrapv. Expect thesignals_[1]sentinel on the 5th call. (Done above; reproduced on g++ 13.3.)slot_, run the existing 2-ranktests/comm/test_pcie_dcp_a2a_gpu.py::test_pcie_dcp_a2a_eager_and_cuda_graph_correctnesseager loop withslot_pre-seeded to2147483645, and observe the illegal-memory-access on rank 1 within a handful of iterations plus mismatching output on rank 0. With the fix the loop is clean.slot_ < 2^31.Provenance of the observation
First noted as
§5 — new: int slot_ overflow indexes staging_[-1]in #95 (comment) (a second-reviewer comment on #95). It was never filed as its own issue; #95's body covers a differentslot_concern (host-baked slot parity under graph replay) and does not mention the overflow. Parent issue for context: #95. Related memory-side report: #94.