CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
305 lines
14 KiB
ReStructuredText
305 lines
14 KiB
ReStructuredText
.. meta::
|
||
:description: Compilation workflow of the HIP compilers.
|
||
:keywords: AMD, ROCm, HIP, CUDA, HIP runtime API
|
||
|
||
.. _hip_compilers:
|
||
|
||
********************************************************************************
|
||
HIP compilers
|
||
********************************************************************************
|
||
|
||
ROCm provides tools for compiling HIP applications for use on
|
||
AMD GPUs. The compilers set up the default libraries, and include paths for the
|
||
HIP and ROCm libraries, along with required environment variables. For more
|
||
information, see the :doc:`ROCm compiler reference
|
||
<llvm-project:reference/rocmcc>`.
|
||
|
||
Compilation workflow
|
||
================================================================================
|
||
|
||
HIP provides a flexible compilation workflow that supports both offline
|
||
compilation and runtime or just-in-time (JIT) compilation. Each approach has
|
||
advantages depending on the use case, target architecture, and performance
|
||
needs.
|
||
|
||
The offline compilation is ideal for production environments, where the
|
||
performance is critical, and the target GPU architecture is known in advance.
|
||
|
||
The runtime compilation is useful in development environments or when
|
||
distributing software that must run on a wide range of hardware without the
|
||
knowledge of the GPU in advance. It provides flexibility at the cost of some
|
||
The runtime compilation is useful in development environments or when
|
||
distributing software that must run on a wide range of hardware without prior
|
||
knowledge of the GPU. It provides flexibility at the cost of some
|
||
performance overhead.
|
||
|
||
Offline compilation
|
||
--------------------------------------------------------------------------------
|
||
|
||
Offline compilation is performed in two steps: host and device code
|
||
compilation.
|
||
|
||
- Host-code compilation: On the host side, ``amdclang++`` or ``hipcc`` can
|
||
compile the host code in one step without other C++ compilers.
|
||
|
||
- Device-code compilation: The compiled device code is embedded into the
|
||
host object file. Depending on the platform, the device code can be compiled
|
||
into assembly or binary.
|
||
|
||
For an example on how to compile HIP from the command line, see :ref:`SAXPY
|
||
tutorial <compiling_on_the_command_line>` .
|
||
|
||
Runtime compilation
|
||
--------------------------------------------------------------------------------
|
||
|
||
HIP allows you to compile kernels at runtime using the ``hiprtc*`` API. Kernels
|
||
are stored as a text string, which is passed to HIPRTC alongside options to
|
||
guide the compilation.
|
||
|
||
For more information, see :doc:`HIP runtime compiler <../how-to/hip_rtc>`.
|
||
|
||
.. _gfx_ip:
|
||
|
||
Target GPU architectures (GFX IP)
|
||
=================================
|
||
|
||
Instructions in the AMDGPU instruction set architecture (ISA) are compatible
|
||
only with certain physical GPU architectures. The versioning system that
|
||
abstracts hardware details from compilers and software is called the GFX IP
|
||
version. Each AMD GPU family, such as RDNA or CDNA, defines its own GFX IP
|
||
identifiers. These identifiers specify which instruction formats, memory
|
||
models, and compute features are supported by that generation of hardware.
|
||
|
||
A GFX version is expressed as a short string, for example:
|
||
|
||
* ``gfx90a`` — CDNA2 (MI250 series)
|
||
* ``gfx942`` — CDNA3 (MI300 series)
|
||
* ``gfx1100`` — RDNA3 (RX 7900 series)
|
||
|
||
Most GFX IP versions are composed of three numerical fields, which act roughly
|
||
like a major-minor-subminor versioning system:
|
||
|
||
* The major version corresponds to the architectural family (for example,
|
||
CDNA3 versus RDNA3).
|
||
* The minor version encodes core feature updates within that family (for
|
||
example, new :ref:`MFMA <mfma_units>` or :ref:`LDS <lds>` capabilities).
|
||
* The subminor version may specify packaging or stepping differences (for
|
||
example, MI300A versus MI300X).
|
||
|
||
Each new generation introduces additional hardware features, for example,
|
||
mixed-precision MFMA instructions, asynchronous data movement engines, and
|
||
updated cache hierarchies, while maintaining broad forward compatibility for
|
||
code compiled at the intermediate representation (IR) level. When compiling GPU
|
||
programs with ``amdclang++``, the target GFX architecture determines the ISA
|
||
and hardware features available to the kernel.
|
||
|
||
For example, compiling for the MI300X would use:
|
||
|
||
.. code-block:: shell
|
||
|
||
amdclang++ --offload-arch=gfx942 kernel.cpp -o kernel.out
|
||
|
||
The compiler uses this flag to emit optimized machine code for that GPU's
|
||
:ref:`compute units <compute_unit>`, :ref:`matrix cores <mfma_units>`, and
|
||
memory subsystem. The GFX IP acts as a virtual hardware target, decoupling
|
||
high-level programming models (HIP, OpenMP, OpenCL) from the underlying physical
|
||
GPU design.
|
||
|
||
While AMD does not explicitly name its compatibility model as "onion-layered,"
|
||
the GFX IP system follows a similar principle: newer architectures generally
|
||
extend, rather than break, existing instruction sets.
|
||
|
||
Thus, code compiled for an older architecture (for example, ``gfx90a``) can
|
||
often be re-optimized or recompiled for a newer one (``gfx942``) with minimal
|
||
modification. However, compatibility is not guaranteed across major GFX
|
||
families, since those may introduce fundamentally new pipelines or execution
|
||
semantics.
|
||
|
||
.. _amdgpu_assembly:
|
||
|
||
AMDGPU assembly
|
||
===============
|
||
|
||
AMDGPU assembly, sometimes called GFX ISA (Instruction Set Architecture), is
|
||
the low-level assembly format for programs running directly on AMD GPUs. It is
|
||
the lowest-level human-readable representation of GPU instructions, typically
|
||
generated by the ROCm compiler toolchain and converted into binary microcode
|
||
for execution on the device.
|
||
|
||
Each AMD GPU architecture family, such as RDNA or CDNA, defines its own GFX ISA
|
||
version. For example:
|
||
|
||
* ``gfx90a`` corresponds to CDNA2 (MI250 series)
|
||
* ``gfx942`` corresponds to CDNA3 (MI300 series)
|
||
* ``gfx1100`` corresponds to RDNA3 consumer GPUs
|
||
|
||
Each version defines its unique instruction encodings, supported data types,
|
||
and pipeline behavior. Compiled GPU kernels must target a specific :ref:`GFX
|
||
architecture <gfx_ip>` to ensure instruction compatibility and optimal
|
||
scheduling.
|
||
|
||
AMDGPU assembly is rich and expressive, exposing every level of GPU behavior:
|
||
scalar operations, vector math, memory access, synchronization, and
|
||
matrix-multiply instructions. A few examples of instructions from the
|
||
``gfx942`` architecture include:
|
||
|
||
* ``v_add_f32 v0, v1, v2`` — add 32-bit floats in vector registers
|
||
* ``s_mov_b32 s4, 0x3f800000`` — move immediate value (1.0f) into a scalar
|
||
register
|
||
* ``v_mfma_f32_16x16x4f16 v[0:15], v[16:31], v[32:47], v[0:15]`` — perform a
|
||
16×16×4 matrix fused multiply-add
|
||
* ``s_barrier`` — synchronize all warps in the work-group
|
||
|
||
In this syntax:
|
||
|
||
* ``v_`` instructions operate on vector registers (VGPRs) per thread.
|
||
* ``s_`` instructions operate on scalar registers (SGPRs) shared by the warp.
|
||
* Specialized matrix instructions (``v_mfma_*``) invoke the :ref:`Matrix Core
|
||
(MFMA) hardware units <mfma_units>`.
|
||
|
||
While it is possible to write AMDGPU assembly by hand, this practice is rare. In most cases, developers review compiler‑generated assembly to optimize kernels, analyze register pressure, or refine memory‑access behavior.
|
||
|
||
The ROCm disassembler (``llvm-objdump``) and ROCm profiler (``rocprofv3``)
|
||
allow inspection of generated GFX ISA alongside high-level HIP or OpenMP source
|
||
code. Because the instruction semantics and binary encodings are publicly
|
||
documented by AMD, the GFX ISA is a fully open, compiler-targetable standard.
|
||
|
||
This openness allows tool developers, performance engineers, and researchers to
|
||
reason about GPU behavior at the instruction level, bridging the gap
|
||
between hardware and high-level kernel code.
|
||
|
||
.. _amdgpu_ir:
|
||
|
||
AMDGPU intermediate representation
|
||
===================================
|
||
|
||
AMDGPU intermediate representation (AMDGPU IR) is an intermediate
|
||
representation for code that runs on AMD GPUs and other parallel processors. It
|
||
is one of the key outputs of the ROCm compiler toolchain, produced by
|
||
``amdclang++`` before being translated into architecture-specific GPU assembly
|
||
(:ref:`GFX ISA <amdgpu_assembly>`).
|
||
|
||
AMD documentation refers to this layer as both a virtual instruction set and
|
||
a target-specific dialect of LLVM IR. From a programmer's perspective, AMDGPU
|
||
IR defines a virtual machine model for parallel thread execution: compilers and
|
||
optimizers emit this IR with the expectation that it will execute with consistent semantics
|
||
across multiple generations of AMD hardware, including future architectures not
|
||
yet released.
|
||
|
||
This makes AMDGPU IR a "narrow waist" between software and hardware,
|
||
abstracting the details of the physical :ref:`compute units <compute_unit>`,
|
||
:ref:`warp <wavefront>` schedulers, and memory hierarchies, while still
|
||
providing explicit control over threads, registers, and memory spaces.
|
||
|
||
Unlike traditional CPU ISAs, AMDGPU IR is not executed directly. Instead, it is
|
||
further compiled (either just‑in‑time or ahead‑of‑time) into GFX ISA, the
|
||
device-specific binary that runs on a given GPU architecture (for example,
|
||
``gfx942`` for CDNA3 MI300X or ``gfx1200`` for RDNA3). This multi-stage
|
||
compilation allows forward compatibility: kernels compiled for one generation
|
||
can often be re-optimized and executed efficiently on newer hardware through
|
||
updated ROCm runtimes and drivers. Some exemplary fragments of AMDGPU IR:
|
||
|
||
.. code-block:: llvm
|
||
|
||
; declare usage of 64 vector registers
|
||
!amdgpu.num_vgpr = !{i32 64}
|
||
|
||
; perform fused multiply-add
|
||
%f5 = call float @llvm.fma.f32(float %f3, float %f4, float 1.5)
|
||
|
||
; read thread and workgroup indices
|
||
%tid = call i32 @llvm.amdgcn.workitem.id.x()
|
||
%wgid = call i32 @llvm.amdgcn.workgroup.id.x()
|
||
|
||
These instructions represent operations in the virtual machine model:
|
||
|
||
* Registers are virtual VGPRs/SGPRs dynamically mapped to physical hardware
|
||
registers by the compiler.
|
||
* Arithmetic and memory intrinsics (``llvm.fma``, ``llvm.amdgcn.buffer.load``)
|
||
map one-to-one to GPU instructions.
|
||
* Built-in functions like ``llvm.amdgcn.workitem.id.x()`` access special
|
||
per-thread state, such as the current thread or
|
||
:ref:`block <inherent_thread_hierarchy_block>` index.
|
||
|
||
The AMDGPU IR machine model reflects the hardware reality of AMD GPUs: a single
|
||
instruction stream drives a :ref:`wavefront <wavefront>` of 64 threads that
|
||
execute in lockstep on the SIMD pipelines, each maintaining its own register
|
||
state while sharing program flow and :ref:`local memory <lds>`.
|
||
Warps cooperate through the :ref:`Local Data Share (LDS) <lds>` and synchronize
|
||
via barriers, the same abstractions exposed in the high-level ROCm programming
|
||
model.
|
||
|
||
Since AMDGPU IR is integrated with the open-source LLVM compiler
|
||
infrastructure, its syntax and semantics are well-documented and publicly
|
||
accessible. Developers can inspect, modify, or emit AMDGPU IR directly for
|
||
performance analysis, research, or custom toolchains.
|
||
|
||
.. _binary_utilities:
|
||
|
||
ROCm binary utilities
|
||
=====================
|
||
|
||
The ROCm binary utilities are a collection of command-line tools for examining
|
||
and manipulating GPU binaries produced by ``amdclang++`` or other ROCm build
|
||
tools. These utilities allow developers to inspect, disassemble, and analyze
|
||
AMDGPU code objects, the compiled GPU kernels embedded in host executables or
|
||
distributed as standalone ``.hsaco`` files. Previous ROCm versions shipped with the ``roc-obj-ls``,
|
||
``roc-obj-extract``, and ``roc-obj utilities``. These have been deprecated in favor of enhanced
|
||
capabilities now available in standard LLVM object tools, such as ``llvm-objdump`` and
|
||
``llvm-readobj``. For more information, see `llvm-objdump — LLVM’s object file dumper at
|
||
<https://llvm.org/docs/CommandGuide/llvm-objdump.html>`__.
|
||
|
||
The ``llvm-objdump`` utility provides multiple capabilities for analyzing GPU
|
||
binaries. With the ``--offloading`` flag, it can list and extract information
|
||
from the contents of ROCm binaries, including code object metadata, kernel
|
||
symbols, target architectures (for example, ``gfx90a``, ``gfx1100``), and
|
||
linkage details. It supports both standalone ``.hsaco`` files and "fat
|
||
binaries" stored as embedded objects within host executables. In current releases, the tool
|
||
additionally extracts HIP fat‑binary bundle entries into standalone code object files. With the
|
||
``--triple=amdgcn`` option, it can disassemble GPU kernels into readable AMDGPU ISA, allowing
|
||
detailed examination of instruction streams, register usage, and control‑flow structure. Such
|
||
capabilities are critical for performance tuning, correctness verification, and low‑level kernel
|
||
analysis, including tasks such as optimizing :ref:`MFMA <mfma_units>` instructions or assessing
|
||
compiler‑generated transformations.
|
||
|
||
The ``llvm-readobj`` tool, used with the ``--offloading`` flag, provides a complete listing of HIP fat‑binary offload bundle entries, superseding the earlier ``roc-obj-ls`` utility.
|
||
|
||
Together, these utilities provide developers with insight into how HIP C++ code
|
||
is compiled, optimized, and mapped to GPU hardware. They complement profiling
|
||
tools like ``rocprofv3`` by exposing the static structure of compiled GPU
|
||
binaries.
|
||
|
||
Static libraries
|
||
================================================================================
|
||
|
||
``amdclang++`` supports generating two types of static libraries.
|
||
|
||
- The first type of static library only exports and launches host functions
|
||
within the same library and not the device functions. This library type
|
||
offers the ability to link with another compiler such as ``gcc``.
|
||
Additionally, this library type contains host objects with device code
|
||
embedded as fat binaries. This library type is generated using the flag
|
||
``--emit-static-lib``:
|
||
|
||
.. code-block:: shell
|
||
|
||
amdclang++ hipOptLibrary.cpp --emit-static-lib -fPIC -o libHipOptLibrary.a
|
||
gcc test.cpp -L. -lhipOptLibrary -L/path/to/hip/lib -lamdhip64 -o test.out
|
||
|
||
- The second type of static library exports device functions to be linked by
|
||
other code objects by using ``amdclang++`` as the linker. This library type
|
||
contains relocatable device objects and is generated using
|
||
``ar``:
|
||
|
||
.. code-block:: shell
|
||
|
||
amdclang++ hipDevice.cpp -c -fgpu-rdc -o hipDevice.o
|
||
ar rcsD libHipDevice.a hipDevice.o
|
||
amdclang++ libHipDevice.a test.cpp -fgpu-rdc -o test.out
|
||
|
||
Examples of this can be found in `rocm-examples
|
||
<https://github.com/ROCm/rocm-examples>`_ under `static host libraries
|
||
<https://github.com/ROCm/rocm-examples/tree/develop/HIP-Basic/static_host_library>`_
|
||
or `static device libraries
|
||
<https://github.com/ROCm/rocm-examples/tree/develop/HIP-Basic/static_device_library>`_.
|