Files
TheRock/rocm-systems/emulation/rocjitsu/docs/rocjitsu_dbt_guest.md
T
derek.holloway 7502bf64a4
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
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

172 lines
7.9 KiB
Markdown

# rocjitsu DBT Guest Mode
A rocjitsu-only path where an unmodified ROCm process can see a guest GPU, but
translate kernels and execute on either a real or simulated host GPU.
The design has three main components with their own responsibilities:
1. **GuestKfd Interposer**: Shows applications a guest GPU device that looks
like a real KFD/DRM device.
2. **HSA Hooks**: Intercepts HSA Runtime calls for the guest GPU and forwards
them to the selected host backend, translating kernels as needed.
3. **DBT**: Translates guest GPU kernels to host GPU kernels.
The `dbt_guest.execution_backend` enum selects `hardware` or `simulator`.
Simulator mode can reference an external host config with `simulator_config`,
which takes precedence over VM/topology in the enclosing file, or omit that
field and keep the simulator VM/topology in the same file. The checked-in
CDNA4-on-CDNA3 config references the golden CDNA3 simulator config; the
self-contained layout is primarily useful for tests and temporary configs.
The optional `dbt_guest.guest_revision` and `dbt_guest.host_revision` enums carry
the silicon revision for each translation side. They are needed only for
gfx1250, whose A0 and B0 steppings share an ELF machine ID and therefore cannot
be told apart from the code object alone. A same-ISA gfx1250 load is rejected
unless both revisions are set so the corresponding translation profile can be
selected. For every other target the machine ID identifies the silicon, so
these fields stay `unspecified`.
## High Level Flow
User:
```bash
rocjitsu --config configs/guest_gfx950_on_gfx942.json -- ./app
```
Underneath:
```
LD_PRELOAD=librocjitsu.so
open/read sysfs topology -> host topology plus synthetic gfx950 node
open/ioctl /dev/kfd -> real KFD for host nodes, GuestKfd for guest discovery/startup
HSA_TOOLS_LIB=librocjitsu_hooks.so
ROCR internally sees -> selected host agent plus synthetic guest agent
hsa_iterate_agents -> public host slot is replaced by the guest agent
hsa_agent_get_info -> guest still reports gfx950 identity
hsa_queue_create -> guest agent is replaced with host agent
hsa_executable_load... -> guest ELF translated to host ELF, then loaded on host
hsa_executable_get... -> guest symbol lookup is replaced with host symbol lookup
AMD extension calls -> guest agents are replaced with host agents where needed
```
## Design Principles
1. ROCR must internally discover both the real host GPU and the synthetic guest
GPU.
The selected host must stay available for queues, allocations, and code
loading. The synthetic guest must also exist so ROCR can build the guest HSA
agent. Public HSA iteration is then shadowed: rocjitsu emits the guest agent
in the selected host's ordinal slot and suppresses the guest's own slot. This
keeps applications that choose the first GPU on the guest path while leaving
the host agent alive for execution.
If `ROCR_VISIBLE_DEVICES` is set, the launcher expands it so the selected
host ordinal and appended guest ordinal both remain visible to ROCR before
the HSA hook applies this public shadowing.
2. Guest-facing discovery stays guest-shaped.
Calls that applications use to decide which kernel image to load, such as
agent name and ISA iteration, should report the synthetic guest agent. If we
mapped those calls to the host, the application would choose host kernels
and skip DBT.
3. Execution-facing calls map guest handles to host handles.
Queue creation, code-object load, symbol lookup, memory access, and AMD
extension operations that take an agent are redirected from the guest agent
to the selected host agent.
4. KFD emulation stops at guest discovery.
`GuestKfd` should not run queues, allocate real guest VRAM, or process AQL
packets. It does handle enough startup plumbing for ROCR discovery: process
apertures, clock counters, VM acquisition, available-memory queries, memory
policy setup, synthetic guest memory handles, and guest-to-host gpu_id
rewrites for map/unmap requests. If a guest execution ioctl is reached after
the HSA hooks are in place, that is a missed HSA interception and should be
visible in logs.
5. Code objects are loaded against the host ROCR agent.
ROCR validates code-object ISA against the load agent using ELF header
fields. The hook translates the ELF to host ISA and calls the original
`hsa_executable_load_agent_code_object()` with the host agent, not the guest
agent. Symbol queries using the guest agent are later remapped to the host
agent so application code still works.
## Architecture
rocjitsu DBT guest mode has two layers:
1. A Linux KMD/driver interposer that makes the process believe a synthetic GPU
exists.
2. An HSA tools hook that forwards synthetic-GPU work to the selected real host
GPU and translates guest code objects to host code objects.
These layers solve different problems and should stay separate.
### KMD Driver Interposer
Applications do not always use HSA as their only GPU discovery path. Some
frameworks and tools inspect `/dev/kfd`, KFD topology sysfs, DRM render nodes,
or AMDGPU device metadata directly. If rocjitsu only hooks HSA, those clients
may never believe a guest GPU exists.
The KMD layer therefore appends a synthetic GPU to KFD topology and exposes a
matching synthetic DRM render node. Its job ends at discovery and startup
plumbing. It should not execute guest queues or emulate packet dispatch for this
DBT path.
For host-facing operations, `GuestKfd` forwards to the real `/dev/kfd`. For
guest-facing startup operations, it either answers from the synthetic metadata
or rewrites the request to the configured host GPU. Guest doorbell mappings and
unsupported guest execution ioctls fail visibly.
### HSA Hooks
Applications generally dispatch through HSA. HSA API calls are mostly target
independent, but AQL packets, queue resources, code-object ISA validation, and
some extension calls carry target-specific meaning. Patching every packet and
every target-dependent field after queue creation is too fragile.
Instead, ROCR builds two HSA agents:
- the selected host agent, backed by the real GPU and real KFD execution path;
- the synthetic guest agent, backed by the KFD overlay and guest metadata.
The HSA hook presents one public replacement agent: the guest agent in the
selected host's enumeration slot. Execution-facing guest handles are then mapped
back to the host agent. When a guest code object is loaded, the hook translates
the code object to the host ISA and calls ROCR's original load API with the host
agent. Kernel dispatch then uses normal host queues and normal host ROCR
execution machinery.
The important invariant is:
```text
public identity: guest agent, guest ISA, guest name, guest memory pools
execution identity: host agent, host queues, host memory backing, host code object
```
## Known Limits and Follow-Ups
- File-backed HSA code-object readers are not translated in the MVP. Add a way
to capture stable bytes from `hsa_file_t` if an application needs this path.
Today the hook prints a warning when such a reader is created, and guest loads
without registered memory bytes fail rather than retrying an incompatible
original ELF.
- `HSA_TOOLS_DISABLE_REGISTER=1` is a workaround. The better design is a
rocprofiler-register API-table interposer that applies the same shadowing
before rocprofiler validates HSA agents.
- KFD guest queue execution is intentionally unsupported. If a guest execution
ioctl is reached, add or fix an HSA forwarding hook rather than teaching
`GuestKfd` to execute packets.
- `signal_backtrace` is an opt-in best-effort diagnostic. rocjitsu prewarms the
unwinder before installing the handler, but fatal-signal stack unwinding can
still hang if unwinder or loader state is corrupted.
- DBT guest mode is local-launch only right now. Daemon and attach modes still
belong to the simulation path.
- IPC and advanced multi-process memory sharing are out of scope for the MVP.