mirror of
https://github.com/deepseek-ai/DeepGEMM.git
synced 2026-11-05 00:47:26 +00:00
[PR #426] [Bug] Fix bench_kineto returning zero on the first call in a process #437
Labels
No labels
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
deepseek-ai/DeepGEMM#437
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
📋 Pull Request Information
Original PR: https://github.com/deepseek-ai/DeepGEMM/pull/426
Author: @HangruiCao2000
Created: 9/2/2026
Status: 🔄 Open
Base:
main← Head:fix/bench-kineto-first-call-empty-table📝 Commits (1)
af9e1edFix bench_kineto returning zero on the first call in a process📊 Changes
1 file changed (+23 additions, -0 deletions)
View changed files
📝
deep_gemm/testing/bench.py(+23 -0)📄 Description
Summary
bench_kinetoreturns0for every kernel on the first call in a process. The firsttorch.profiler.profile(activities=[CUDA])session records no device activity at all —key_averages()comes back empty, nothing matches any kernel name, and the parser falls through to itselse 0branch.Since the first
bench_kinetocall in each test file feeds a division, six of our own test files abort four frames away from the cause:test_bf16,test_fp8_fp4,test_einsum,test_attention,test_hyperconnectionandtest_legacyall fail this way.test_layoutsurvives only because it happens to guard its division — it silently reports its first shape as0 us | 0 GB/sinstead.Root cause
This is a property of the profiler, not of DeepGEMM. It reproduces with no DeepGEMM code at all, and only the first session in the process is affected:
I tried each candidate fix in a fresh process:
wait=0, warmup=1, active=1)wait=1, warmup=2, active=1, 4 iters)ProfilerActivity.CPUMore warmup steps do not help, so this is CUPTI lazy initialization at session level rather than a schedule problem. Adding
ProfilerActivity.CPUalso works, but it puts CPU op rows in the table where they can match kernel-name substrings and trip the existing uniqueness assertion — so this PR uses the throwaway session. Itswithbody is empty, so it runs no GPU work and costs nothing.Changes
_warmup_kineto()— open and close one empty profiler session, once per process, before the measured session.reducename intest_bf16when there is no split-K), so that case must keep returning0; but a table with no device activity at all is always a profiling failure and should say so rather than report every kernel as infinitely fast.test_layoutalready wraps its call intry/except AssertionError, so it is unaffected.Verification
Measured end-to-end on GB200 / sm_100a: capability
(10, 0),get_arch_major() == 10, cubins built forsm_100(cuobjdump --list-elf->kernel.sm_100.cubin), aarch64, CUDA 13.1, PyTorch 2.9.0+cu130,third-party/cutlassat the pinnedf3fde58.Determinism. Unpatched
tests/test_bf16.pyfails 3/3 independent runs with the identical traceback. Patched, it passes.Recovered data point.
tests/test_layout.py, first row:3 us | 49 GB/sis what the same shape measures later in the same run, and every subsequent row is unchanged.Paired first-call check against a real sm100 kernel, at
test_bf16's actual first shape and at a large square:Post-fix call 0 agrees with calls 1 and 2 to within run-to-run noise: the warmup recovers the measurement without shifting it.
Rows produced. Perf rows emitted, and how many of them read
0.0 us:test_bf16test_fp8_fp4test_einsumtest_bf16also now reportsAverage speedup over cuBLASLt: 0.894x, an aggregate that previously could not be computed at all. Coverage spans the sm100 GEMM family:sm100_bf16_gemm,sm100_bf16_k_grouped_gemm,sm100_bf16_m_grouped_gemm_contiguous,sm100_bf16_m_grouped_gemm_masked,sm100_fp8_fp4_gemm_1d1d,sm100_tf32_hc_prenorm_gemm,sm100_bmn_bnk_mn_gemm.Out of scope
Two test files fail on this machine both before and after, for reasons unrelated to this bug:
test_mega_moeneeds at least 6 GPUs (ValueError: device_id cuda:5 is out of range); this box has 4.test_sanitizerhits a JIT assertion under compute-sanitizer's build flags:not std::regex_search(output, std::regex(R"(Local memory used)"))while compilingfp8_gemm_nt_skip_head_mid, i.e. that kernel spills local memory. Reported separately if useful.🤖 Generated with Claude Code
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.