Dear nVidia team and other forum visitors,
On H200 NVL GPU, I am trying to reach TFLOPS as reported on its datasheet:
On page 4, under FP16 Tensor Core (2: with sparsity), there is 1671 TFLOPS.
I assume dense=sparse / 2 (as this was the case in many other more detailed datasheets that I saw).
So I think 835.5 TFLOPS is correct number for dense FP16 FMA with FP32 accumulation.
Please correct me if this is wrong, ideally with a citation to a detailed technical document – I couldn’t find one for the H200 series.
Next, I am doing following simple bechmark.
Make matrix A of size M=K, and matrix B with size K, N with fp16 dtype. I sweep through two variables, M=K and N.
Record the time it takes to make large number of multiplications after a warmup.
The code is roughly this (full code attached):
import torch
def gemm_flops(m: int, n: int, k: int) -> float:
return 2.0 * m * n * k
a = torch.randn(shape.m, shape.k, device="cuda", dtype=torch.float16)
b = torch.randn(shape.k, shape.n, device="cuda", dtype=torch.float16)
c = torch.empty(shape.m, shape.n, device="cuda", dtype=torch.float16)
flops = gemm_flops(shape.m, shape.n, shape.k)
for _ in range(config.warmup_iters):
torch.mm(a, b, out=c)
torch.cuda.synchronize()
for _ in range(config.repeats):
start_event = torch.cuda.Event(enable_timing=True)
end_event = torch.cuda.Event(enable_timing=True)
start_event.record()
for _ in range(config.measure_iters):
torch.mm(a, b, out=c)
end_event.record()
end_event.synchronize()
elapsed_seconds = start_event.elapsed_time(end_event) / 1e3
seconds_per_iter = elapsed_seconds / config.measure_iters
tflops = flops / (seconds_per_iter * 1e12)
Maximum I was able to get is 712 TFLOPS, so about 85% of the max GPU TFLOPs.
What am I missing to reach 100% ?
On consumer GPU (RTX 3070) the same benchmark got up to 105%, which I think is due to overclocking.
But I have a hard time to close the 15% gap on the H200.
Some explanations that come to mind:
- Torch/other libraries in the stack do not use optimal matmul implementations.
- The gemm operations use another algorithm for matmuls than the O(n^3), so gemm_flops is wrong.
- There are unaccounted effects, like variable clock speed.
- Measurement is somehow wrong.
- I have wrong max FLOPs number.
- It’s indeed impossible to reach manufacturer’s claims of the theoretical flops.
I report also the power draw during the matmuls.
system.txt (18.5 KB)
gemm_bench.py.txt (11.3 KB)
Thank you very much for any help / pointers!
Sincerly,
Michal Sustr
