Files
TheRock/rocm-systems/emulation/rocjitsu/docs/isa-target-providers.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

5.3 KiB

ISA Target Providers

Each final executable or shared object selects one static ISA target set. The resulting IsaTargetRegistry is an immutable view over constexpr descriptors; there is no process-global registry, runtime registration, or plugin ABI. Separate linked images may select different subsets without creating a global union.

Providers simplify source-integrated new-product introduction (NPI) and per-image composition. They do not make RocJITsu open-world: a target with new semantics may still require changes to public enums, ISA traits, code-object handling, analysis, DBT, patching, or simulation in the downstream source tree.

Defining a provider

A provider header publishes its complete constexpr descriptor. Its aliases, GPU metadata, and decoder factory are all static:

std::unique_ptr<rocjitsu::Decoder> create_target_decoder();

inline constexpr IsaTargetDescriptor kTargetDescriptor{
    .id = "vendor-next",
    .architecture_id = ROCJITSU_CODE_ARCH_VENDOR_NEXT,
    .gpu_targets = kGpuTargets,
    .decoder_factory = &create_target_decoder,
    .supports_execution = true,
};

The canonical string ID and aliases identify the target within the selected registry. The optional architecture and GPU bindings connect it to RocJITsu's closed public enums, offload-bundle processor names, and ELF machine values.

The header remains safe to include normally. An opt-in section after its include guard exposes the descriptor to registry composition:

#ifdef ROCJITSU_GET_ISA_TARGET_DESCRIPTOR
ROCJITSU_GET_ISA_TARGET_DESCRIPTOR(vendor::kTargetDescriptor)
#endif

The provider source owns decoder implementation details:

std::unique_ptr<rocjitsu::Decoder> create_target_decoder() {
  return make_isa_decoder<VendorIsa>();
}

Mark the ISA implementation target as a provider. The provider source is compiled with that existing target; CMake records only its declaration header.

rj_add_object_library(vendor_isa decoder.cpp target_provider.cpp)
rj_add_isa_target_provider(
    vendor_isa
    HEADER vendor/target_provider.h
)

Registry construction validates the selected descriptors. A composition error is reported by ok() and error(), and lookup fails closed.

Composing a target set

Each final linked image defines one default registry from its exact provider list:

rj_add_isa_target_registry(
    errata_isa_registry
    PROVIDERS rocjitsu_isa_gfx1250_model
)

The simulator uses ${RJ_BUILTIN_ISA_PROVIDERS} instead, while an AMDGPU-specific tool can select the AMDGPU-only list. A source-integrated downstream provider can likewise be selected by only the tool that needs it.

CMake generates only an include list of the selected provider headers. The common composition source uses it to form a static constexpr descriptor array, preserving the provider collection order, then constructs the registry once over that immutable storage. Explicit descriptor factory references avoid static constructors and --whole-archive. Removing a provider removes that registry's direct dependency on its implementation.

Exactly one registry composition may be linked into an executable or shared object because it defines that image's default_isa_target_registry() and enum-based decoder entry point.

Querying support

The default registry is the C++ source of truth for the targets present in one linked image:

const IsaTargetRegistry &registry = default_isa_target_registry();
if (!registry.ok())
  report_registry_error(registry.error());

for (const IsaTargetDescriptor &target : registry.targets())
  publish_supported_target(target.id, target.supports_execution);

if (registry.find(requested_target) == nullptr)
  report_unsupported_target(requested_target);

targets() enumerates descriptors in the provider order passed to rj_add_isa_target_registry(). Built-in provider lists preserve the order in which their CMake subdirectories register them. find() accepts a canonical ID, alias, integrated architecture enum, or integrated GPU target.

Direct registry construction accepts only const lvalue descriptor arrays. The array and every aliases/GPU metadata array referenced by it must remain alive and unchanged for the registry's lifetime; provider compositions meet that contract with inline constexpr storage.

The public C API does not enumerate the internal registry. It can probe the selected subset by name with rj_code_decoder_create_for_target("gfx1250", &decoder). An unavailable target returns a recoverable error.

Model-only gfx1250

gfx1250 supplies separate full and model-only providers. Select exactly one in each registry. The model-only provider links the decoder/model objects without the execution objects, and decoded instructions have a null execution callback. ModelOnlyIsaTest.SymbolBoundary and Gfx1250B0ToA0Library.SymbolBoundary verify that execution and VM symbols do not enter those final binaries.

Adding an NPI target

  1. Add the target description and provider source to the ISA implementation target.
  2. Add public architecture or GPU enum entries only when the public enum or code-object APIs must address the target.
  3. Select the provider in each executable or shared object that should contain it.
  4. Follow the existing \NPI markers for the remaining closed-world integration work.

See npi.md for the broader product checklist.