Conversation
Remove .all() device-host sync assertions from pack_ue8m0_to_int that cause cudaErrorStreamCaptureUnsupported when called inside a captured CUDA graph (e.g. SGLang decode graph via MegaMoE FP8 staging). The two removed checks: (x_int >= 0).all() # non-negative exponent (x_int & 0x7FFFFF == 0).all() # zero mantissa are guaranteed by ceil_to_ue8m0, the only producer of these scale factors: it constructs bits as (exp.clamp(1,254) << 23), which always has a zero mantissa and a positive exponent. Moving the checks to the caller (or relying on the kernel's own malformed-data trap) keeps the capture path free of synchronisations without weakening correctness. Co-Authored-By: Claude <noreply@anthropic.com>
🤖 ds-review-bot Code Reviewv6该改动解决了 CUDA Graph 捕获同步问题,但不必要地在所有执行路径移除了既有输入校验,导致非法输入被静默错误编码。 v5该 MR 移除了 deep_gemm/utils/math.py 中 pack_ue8m0_to_int 内对设备张量的两个 v4p本 MR 移除 Files reviewed: 1 |
ds-review-bot v6: removing all device-side checks silently corrupted invalid inputs from direct callers or upstream regressions. Fix: keep the .all() asserts outside CUDA graph capture (loud error on bad input), skip them during capture (device->host sync forbidden). Co-Authored-By: Claude <noreply@anthropic.com>
…edge case) x.round() rounds subnormal values like 2^-126 to 0, causing false asserts. Use integer bit manipulation instead: sign bit == 0 and mantissa bits == 0. Co-Authored-By: Claude <noreply@anthropic.com>
…stions - Add docstring documenting the UE8M0 precondition, why downstream kernels cannot catch violations (they only validate shape/dtype), and why capture-safe skipping is correct - Remove inaccurate comment 'kernel itself traps on malformed scales' (sm100_mqa_logits / sm100_fp8_fp4_gemm_1d1d only validate shape/dtype) Co-Authored-By: Claude <noreply@anthropic.com>
|
Thanks for the detailed review! Here's what was addressed: v6 warning (silent corruption on invalid input outside capture):
v4p suggestion (inaccurate comment "kernel itself traps on malformed scales"): v5 suggestion (document preconditions): Tested on H200 (CUDA 12.8):
|
|
I independently reproduced #414 while investigating the SGLang MegaMoE workaround. Your current capture-aware guard fixes the failure for valid inputs — verified on an RTX 3060 with PyTorch 2.6.0 + CUDA 11.8 (eager warm-up, then I found two small follow-ups that may be useful:
I prepared the changes as a single commit on top of your current head (ba14b91): Local results: Happy for you to cherry-pick the commit, or I can open a PR against your branch if that is easier. |
Guard the capture query with x.is_cuda so CPU inputs keep eager value validation without querying CUDA capture state, and reuse the existing x_int bit view instead of creating a second one. Add regression coverage: CUDA graph capture/replay bit-equality against eager execution, replay after mutating the static input buffer (to verify packing is recorded and recomputed by the graph), and eager malformed-input rejection (nonzero mantissa, negative sign).
|
Thanks a lot @200lz — cherry-picked your commit
Verified on an H200 (torch 2.10 / CUDA): all four checks pass against the real Appreciate the independent repro and the follow-up. |
|
Closed the three remaining review threads after rechecking the current head |
Problem
pack_ue8m0_to_intcalled.all()on device tensors:Inside a CUDA graph capture region,
.all()triggers a device→host sync which raisescudaErrorStreamCaptureUnsupported, breaking SGLang's decode graph via the MegaMoE FP8 staging path (issue #414).Fix
Use
torch.cuda.is_current_stream_capturing()to gate validation:Bit-level check avoids float rounding edge cases (e.g. subnormals like 2^-126 that
x.round()would incorrectly round to 0).Test (H200, CUDA 12.8)
ceil_to_ue8m0Addresses ds-review-bot v6 concern: validation is preserved outside capture paths.