HIP buys you source-level API compatibility with CUDA. It does not buy you performance compatibility, and the difference is where CUDA-to-AMD migrations lose their schedule.
The naive reading is that HIP is a migration button: run hipify, recompile against ROCm, and the same kernels now serve AMD hardware. Translation usually does go about that smoothly, because the HIP API is deliberately CUDA-shaped — hipMalloc, hipMemcpy, hipLaunchKernelGGL all map onto their CUDA counterparts almost one-to-one. What does not travel is everything you tuned underneath the API.
What is the difference between HIP and CUDA in practice?
CUDA is NVIDIA’s programming model and toolchain. HIP is AMD’s C++ dialect that mirrors the CUDA API closely enough that one source tree can compile for both ROCm and NVIDIA targets. So the honest framing is not “HIP replaces CUDA” but “HIP lets you keep a CUDA-shaped source tree while targeting two vendors.”
The divergence point is the memory and occupancy model. Wavefront width, LDS versus shared-memory sizing, register pressure, and coalescing patterns tuned against a specific NVIDIA architecture do not carry over. A syntactically clean port can compile, produce correct numerics, and still land well below the AMD hardware’s achievable throughput. Teams that expect a migration button meet this during performance triage rather than during translation — which is the expensive place to meet it.
What translates, and what you rewrite
| Layer | Typically mechanical via hipify | Typically hand rework |
|---|---|---|
| Host API calls (alloc, copy, streams, events) | Yes | Rare |
| Kernel launch syntax | Yes | Rare |
| Library calls (cuBLAS → hipBLAS, cuFFT → hipFFT) | Mostly | Where the API surface diverges |
| Warp-level intrinsics and shuffles | Partially | Wavefront-width assumptions |
| Shared-memory tiling and block sizing | No | Yes, per architecture |
| Inline PTX or architecture-specific assembly | No | Full rewrite |
| Occupancy and register-pressure tuning | No | Yes, per architecture |
Read the table as two budgets, not one. The first is translation coverage; the second is tuning. They are estimated separately because they are paid separately.
Two measurements to produce before hardware procurement
Mechanical portability percentages and post-tuning throughput ratios answer whether AMD makes financial sense for your workload. Together those give engineering days to port and a per-node cost delta once performance parity — or a known, quantified gap — is established. That is a shape a procurement decision can actually consume.
We treat this as the API dimension of a GPU performance audit: assess translation coverage and residual tuning effort on the real codebase, not on a vendor compatibility matrix.
The useful posture is unglamorous. Keep one CUDA-shaped tree, accept HIP for what it is, and budget a separate per-architecture tuning pass for the kernels that carry your runtime. The open question on most codebases is narrower than it looks: which handful of kernels dominate the profile, and do their tiling assumptions survive a change in wavefront width?