ROCm / ROCm/AMDMIGraphX

quantize_fp8 calibration crashes: invalid-argument error, segfault, or hang depending on calibration batch construction

Open
#5,196 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
C++
Stars
333
Forks
150
Avg merge
4d 19h
Merged PRs (30d)
54

Description

Environment

  • Hardware: AMD Instinct MI300X (gfx942)
  • ROCm: 7.2.4
  • MIGraphX: 2.15.0.dev+20250912-17-221-gdd11a7555 (the version shipped with ROCm 7.2.4 at /opt/rocm-7.2.4)
  • PyTorch: 2.13.0+rocm7.2
  • Python: 3.12.3

Summary

migraphx.quantize_fp8(prog, target, calibration_data) fails in three different ways depending on exactly how the calibration data list is constructed, for the same model/target/shape. None of these are Python-catchable in the crash cases — this looks like a native bug, not a usage error I can work around from Python.

Repro model

Any ONNX model works; mine was a transformer-block-shaped module (LayerNorm → Linear(2048,6144) QKV → SDPA attention → Linear(2048,2048) → LayerNorm → MLP) exported from PyTorch at input shape (1, 3600, 2048) fp32. Happy to attach the exact .onnx file if useful — omitted here since it's synthetic and not load-bearing to the bug.

Case 1: list comprehension of to_gpu(argument(...)) → deterministic RuntimeError

import migraphx
import numpy as np

prog = migraphx.parse_onnx("model.onnx")
target = migraphx.get_target("gpu")

calibration_data = [
    {"x": migraphx.argument(np.random.randn(1, 3600, 2048).astype(np.float32))}
    for _ in range(4)
]
migraphx.quantize_fp8(prog, target, calibration_data)
RuntimeError: .../src/targets/gpu/hip.cpp:159: write_to_gpu: Copy to gpu failed: invalid argument

Reproduced deterministically across multiple runs (not GPU-contention related — confirmed via rocm-smi, and reproduced with the device otherwise idle).

Case 2: sequential to_gpu() + migraphx.gpu_sync() after each, building a 4-item calibration list → hard SEGFAULT while building the list

calibration_data = []
for i in range(4):
    arr = np.ascontiguousarray(np.random.randn(1, 3600, 2048).astype(np.float32))
    gpu_arg = migraphx.to_gpu(migraphx.argument(arr))
    migraphx.gpu_sync()
    calibration_data.append({"x": gpu_arg})

migraphx.quantize_fp8(prog, target, calibration_data)

The segfault happens while accumulating the 4 GPU-resident arguments, before quantize_fp8 is even called — no Python traceback, core dumped. 100% reproducible with this construction pattern. See Case 3 for the variant where building the list succeeds but quantize_fp8 itself hangs instead.

Case 3: same sequential+sync construction, quantize_fp8 call hangs indefinitely

# calibration_data built exactly as in Case 2, 4 samples, each to_gpu()'d and synced individually
migraphx.quantize_fp8(prog, target, calibration_data)  # never returns, no error, 60s+ timeout

Case 4 (control): 1 calibration sample, same sequential+sync construction → works cleanly

arr = np.ascontiguousarray(np.random.randn(1, 3600, 2048).astype(np.float32))
gpu_arg = migraphx.to_gpu(migraphx.argument(arr))
migraphx.gpu_sync()
migraphx.quantize_fp8(prog, target, [{"x": gpu_arg}])  # succeeds, compiles cleanly, no crash

Takeaway

The failure mode depends on (a) how many live GPU-resident calibration arguments exist at once and (b) exactly how they're constructed (batch list-comprehension vs. sequential-with-sync) — not on the calibration data itself, which is the same shape/dtype/contiguity in every case. This points to a lifetime/reference-counting or synchronization issue in the calibration path once more than one sample is involved. 1 sample is the only combination I found that's reliably safe, which isn't useful for real calibration quality.

Happy to provide the exact ONNX file or run additional repro variants if that helps narrow it down. Found incidentally while benchmarking, not through a targeted investigation of this code path, so there may be failure modes beyond the four above.

🤖 Filed with assistance from Claude Code

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at the migraphx.quantize_fp8 entry point and trace the GPU calibration path used by the four Python reproductions. Compare the list-comprehension and sequential to_gpu() cases with one-sample calibration, then verify that multiple samples complete without an invalid-argument error, segfault, or hang.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp, python, pytorch
Domain
backend, machine-learning
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.