Skip to content

[310P] Avoid nonzero / per-element host syncs in GDN under TP=4 (v2, rebased on c460a15af) - #23

Open
adeepn wants to merge 1 commit into
upstream-mainfrom
jh/310p-nonzero-free-p2p-c460
Open

[310P] Avoid nonzero / per-element host syncs in GDN under TP=4 (v2, rebased on c460a15af)#23
adeepn wants to merge 1 commit into
upstream-mainfrom
jh/310p-nonzero-free-p2p-c460

Conversation

@adeepn

@adeepn adeepn commented Jun 16, 2026

Copy link
Copy Markdown
Member

What

Re-derive the 310P TP=4 GDN host-stability fix onto current upstream (base upstream-main @ c460a15af).

On Atlas 300I Duo (310P3) under TP=4 with cross-card P2P, two GDN paths fault or stall the host:

  1. initial_state[~has_initial_state, ...] = 0 (gdn_310.py) lowers to aclnnNonzeroV2 plus a
    device→host sync; it faults on some chips and stalls on others → the worker busy-spins inside the
    NPU driver → RCU stall → host hang (only an iBMC reset recovers). Replaced with a nonzero-free
    torch.where helper (_zero_states_without_initial) that also writes an exact 0 for masked rows
    holding NaN/Inf (a state * mask multiply would leak NaN).
  2. _iter_seq_ranges (chunk_gated_delta_rule.py) unpacked cu_seqlens with 2*(N-1) per-element
    .item() syncs sharing the PHB path with cross-card P2P DMA. Collapsed to a single .tolist().

Why a new PR

Supersedes #21. Upstream rewrote gdn_310.py (+250 lines); #21 was authored against an older
snapshot and no longer applies. This re-derives the same fix onto c460a15af (the commit baked into
the current 310P nightly image), preserving the original intent and tests.

Test

  • Unit (CPU, run in the 310P image): tests/ut/_310p/ops/test_gdn_310.py (torch.where vs the
    boolean-index assignment incl. NaN/Inf and a shape-mismatch guard),
    tests/ut/_310p/ops/test_chunk_gated_delta_rule_310.py (_iter_seq_ranges). 23 ut pass.
  • Hardware: Qwen3.6-35B-A3B FP16, TP=4, 4×310P3, image nightly-main-310p (c460a15af): loads,
    serves, tool-calling, prefix-caching (29.9% hit), decode 4.4 t/s, host stable across long runs
    (no hang).

On Atlas 300I Duo (310P3) under TP=4 with cross-card P2P, two GDN code paths
fault or stall the host:

1. The boolean-mask index assignment initial_state[~has_initial_state, ...] = 0
   lowers to aclnnNonzeroV2 plus a device->host sync; the op faults on some chips
   and stalls on others, the worker busy-spins in the NPU driver, and the host
   hangs (only an iBMC reset recovers it). Replace it with a nonzero-free
   torch.where helper (_zero_states_without_initial), which also writes an exact 0
   for masked rows holding NaN/Inf (a state*mask multiply would leak NaN).

2. _iter_seq_ranges unpacked cu_seqlens with 2*(N-1) per-element .item() calls,
   each a device->host sync sharing the PHB path with cross-card P2P DMA. Collapse
   to a single bulk .tolist().

Add CPU unit tests for both helpers.

Signed-off-by: Viacheslav Bocharov <v@baodeep.com>
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.

1 participant