Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
3c18a84
feat(rocke): add gfx1250 runtime capability detection
tenpercent Sep 2, 2026
355e87c
refactor(rocke): make device capability policies extensible
tenpercent Sep 2, 2026
3445c0e
refactor(rocke): separate device identity from capabilities
tenpercent Sep 8, 2026
e6e3fe8
fix(rocke): parse target ID from gfx component
tenpercent Sep 8, 2026
60f69bd
docs(rocke): clarify runtime device identity fields
tenpercent Sep 8, 2026
26cc058
fix(rocke): align device identity target handling
tenpercent Sep 8, 2026
f4fb346
Merge branch 'develop' into users/mpodkory/rocke/aick-2069-runtime-ca…
tenpercent Sep 8, 2026
af04e16
fix(rocke): separate runtime and compiler targets
tenpercent Sep 8, 2026
275b6f7
test(rocke): simplify target identity coverage
tenpercent Sep 8, 2026
52ea3b1
docs(rocke): clarify device and compiler target sources
tenpercent Sep 8, 2026
83c909f
docs(rocke): trace compile targets to their input sources
tenpercent Sep 8, 2026
2c0d1b0
fix(rocke): derive device target names from stored identity
tenpercent Sep 8, 2026
b64c58d
fix(rocke): read versioned HIP device properties with ctypes
tenpercent Sep 9, 2026
4d5d602
refactor(rocke): derive device info from one HIP properties snapshot
tenpercent Sep 9, 2026
db167d7
refactor(rocke): query fresh HIP device properties without caching
tenpercent Sep 9, 2026
cf158b9
test(rocke): verify HIP ctypes layout against native headers
tenpercent Sep 9, 2026
16b1580
Merge branch 'develop' into users/mpodkory/rocke/aick-2069-runtime-ca…
tenpercent Sep 10, 2026
65f7172
fix(rocke): mirror target identity helpers in C++
tenpercent Sep 14, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ test_categories:
quick:
description: "rocKE pre-registered smoke/golden/unit checks (C++ + Python)"
test_patterns:
- "rocke_arch_target_identity"
- "rocke_ir_serialize_roundtrip"
- "rocke_mma_frag_ssot"
- "rocke_tiled_attention_2d_reentrancy"
Expand All @@ -39,6 +40,7 @@ test_categories:
ffm-quick:
description: "Fast-feedback mechanism (FFM) rocKE smoke/golden/unit checks"
test_patterns:
- "rocke_arch_target_identity"
- "rocke_ir_serialize_roundtrip"
- "rocke_mma_frag_ssot"
- "rocke_tiled_attention_2d_reentrancy"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -400,25 +400,97 @@ const char* const* rocke_known_arches(int* count)
return rocke_ati_known_arches;
}

const char* rocke_arch_from_isa(const char* isa, char* out, size_t out_cap)
/* Return the final gfx component without discarding profile or feature suffixes. */
static const char* rocke_target_id_start(const char* isa)
{
const char* dash;
const char* tok;
size_t len;
const char* target = isa;
const char* next = isa;
while((next = strstr(next, "gfx")) != NULL)
{
target = next;
next += 3;
}
return target;
}

if(!isa || !out || out_cap == 0)
return NULL;
/* Python: isa.rsplit("-", 1)[-1] if "-" in isa else isa.
* rsplit on the last '-' yields everything after the final '-'. */
dash = strrchr(isa, '-');
tok = dash ? dash + 1 : isa;
len = strlen(tok);
if(len + 1 > out_cap)
/* Length of the base architecture in target_id; consult the shared catalog so
* names such as gfx11-generic are preserved before removing profile suffixes. */
static size_t rocke_base_arch_length(const char* target_id)
{
size_t name_len = strcspn(target_id, ":");
size_t best = 0;
int i;
for(i = 0; i < rocke_ati_arch_registry_len; ++i)
{
/* Truncate to fit (NUL-terminated); mirrors a best-effort copy. */
len = out_cap - 1;
const char* arch = rocke_ati_known_arches[i];
size_t len = strlen(arch);
if(len <= name_len && strncmp(target_id, arch, len) == 0)
{
if(len == name_len)
return len;
if(target_id[len] == '-' && len > best)
best = len;
}
}
memcpy(out, tok, len);
if(best != 0)
return best;
/* Python's fallback is ^(gfx[0-9a-z]+), with ASCII character semantics. */
if(name_len > 3 && strncmp(target_id, "gfx", 3) == 0)
{
size_t len = 3;
while(len < name_len
&& ((target_id[len] >= '0' && target_id[len] <= '9')
|| (target_id[len] >= 'a' && target_id[len] <= 'z')))
++len;
if(len > 3)
return len;
}
return name_len;
}

static const char* rocke_copy_target(const char* target, size_t len, char* out, size_t out_cap)
{
if(len >= out_cap)
len = out_cap - 1;
memcpy(out, target, len);
out[len] = '\0';
return out;
}

const char* rocke_target_id_from_isa(const char* isa, char* out, size_t out_cap)
{
if(!isa || !out || out_cap == 0)
return NULL;
const char* target = rocke_target_id_start(isa);
return rocke_copy_target(target, strlen(target), out, out_cap);
}

const char* rocke_base_arch_from_target_id(const char* target_id, char* out, size_t out_cap)
{
if(!target_id || !out || out_cap == 0)
return NULL;
return rocke_copy_target(target_id, rocke_base_arch_length(target_id), out, out_cap);
}

const char* rocke_compiler_target_from_target_id(const char* target_id, char* out, size_t out_cap)
{
if(!target_id || !out || out_cap == 0)
return NULL;
size_t name_len = strcspn(target_id, ":");
const char* features = target_id + name_len;
size_t base_len = rocke_base_arch_length(target_id);
if(base_len < name_len && target_id[base_len] == '-')
name_len = base_len;
if(name_len >= out_cap)
return rocke_copy_target(target_id, name_len, out, out_cap);
memcpy(out, target_id, name_len);
rocke_copy_target(features, strlen(features), out + name_len, out_cap - name_len);
return out;
}

const char* rocke_arch_from_isa(const char* isa, char* out, size_t out_cap)
{
if(!isa || !out || out_cap == 0)
return NULL;
return rocke_base_arch_from_target_id(rocke_target_id_start(isa), out, out_cap);
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
* ArchTarget.from_gfx(gfx) rocke_arch_target_from_gfx()
* known_arches() rocke_known_arches()
* arch_from_isa(isa) rocke_arch_from_isa()
* target_id_from_isa(isa) rocke_target_id_from_isa()
* base_arch_from_target_id(id) rocke_base_arch_from_target_id()
* compiler_target_from_target_id(id) rocke_compiler_target_from_target_id()
*
* The Python loader reads core/arch/data/arch_specs.json at import time. The C99
* port embeds that frozen SSOT as static tables (libc-only: no JSON parser), so
Expand Down Expand Up @@ -306,10 +309,25 @@ int rocke_arch_max_threads_per_block(const rocke_arch_target_t* t);
* (excluding the terminating NULL). */
const char* const* rocke_known_arches(int* count);

/* arch_from_isa: extract the gfx token from an isa triple
* ("amdgcn-amd-amdhsa--gfx942" -> "gfx942"). Writes into `out` (>= out_cap) and
* returns `out`. If `isa` has no '-', it is copied verbatim (Python identity
* fallthrough). */
/* Target identity helpers mirror rocke.core.arch.target. They do not validate
* compiler support or query a GPU. Inputs and output buffers must not overlap.
* Each writes at most out_cap - 1 bytes plus a NUL and returns out; a small
* buffer receives a truncated result (the existing arch_from_isa convention).
* NULL input/output or zero capacity returns NULL without writing. */

/* Extract from the last "gfx", preserving profile and feature suffixes.
* If there is no "gfx", copy the input unchanged. */
const char* rocke_target_id_from_isa(const char* isa, char* out, size_t out_cap);

/* Remove features and profiles for catalog lookup, preserving catalog names
* such as gfx11-generic. gfx1250-strict and gfx942:xnack- become gfx1250/gfx942. */
const char* rocke_base_arch_from_target_id(const char* target_id, char* out, size_t out_cap);

/* Remove profiles but preserve compiler features: gfx1250-strict:xnack-
* becomes gfx1250:xnack-. */
const char* rocke_compiler_target_from_target_id(const char* target_id, char* out, size_t out_cap);

/* Extract the target ID from an ISA name, then derive its base architecture. */
const char* rocke_arch_from_isa(const char* isa, char* out, size_t out_cap);

#ifdef __cplusplus
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# Copyright (c) Advanced Micro Devices, Inc., or its affiliates.
# SPDX-License-Identifier: MIT
"""ROCKE architecture metadata package (polymorphic-core SSOT).
"""Architecture metadata and target-name helpers.

Exposes :class:`ArchTarget` and the MMA catalog. Hardware facts only — no
pipeline/scheduler vocabulary, no LLVM intrinsic text, no ``dispatcher/`` imports.
Exposes :class:`ArchTarget`, the MMA catalog, and helpers for converting HIP
and COMGR target names. These helpers read the architecture catalog without
querying a GPU or compiler.
"""

from .target import ( # noqa: F401
Expand All @@ -14,8 +15,11 @@
MmaOp,
ResourceLimits,
arch_from_isa,
base_arch_from_target_id,
compiler_target_from_target_id,
known_arches,
normalize_dtype,
target_id_from_isa,
validate_arch,
)

Expand All @@ -27,7 +31,10 @@
"MmaOp",
"ResourceLimits",
"arch_from_isa",
"base_arch_from_target_id",
"compiler_target_from_target_id",
"known_arches",
"normalize_dtype",
"target_id_from_isa",
"validate_arch",
]
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from __future__ import annotations

import json
import re
from dataclasses import dataclass, field
from functools import lru_cache
from pathlib import Path
Expand Down Expand Up @@ -1095,9 +1096,79 @@ def known_arches() -> Tuple[str, ...]:
return tuple(sorted(_load_specs()))


def target_id_from_isa(isa: str) -> str:
"""Extract the target ID from a COMGR ISA name.

``compile_kernel(..., isa=...)`` passes its ``isa`` argument here. That
value may come from an example's ``--isa`` option, a fixed string in a
script, or the compile helper's ``gfx950`` default. See the input paths
documented in :mod:`rocke.helpers.compile`.

For ``amdgcn-amd-amdhsa--gfx942:sramecc+:xnack-``, this returns
``gfx942:sramecc+:xnack-``, keeping any profile or feature suffix.
It also accepts a target ID without the ISA prefix.

The result starts at the last ``gfx`` in the input. If there is no
``gfx``, the input is returned unchanged. This does not validate the name.
"""

start = isa.rfind("gfx")
return isa[start:] if start >= 0 else isa


def base_arch_from_target_id(target_id: str) -> str:
"""Derive the architecture name used for rocKE catalog lookup and lowering.

Removes features after ``:`` and profile suffixes such as ``-strict``:
``gfx1250-strict`` becomes ``gfx1250`` and ``gfx942:xnack-`` becomes
``gfx942``. Names already in :func:`known_arches`, including
``gfx11-generic``, are preserved.

An unknown name is reduced to its leading ``gfx`` token when possible.
This does not check support; :meth:`ArchTarget.from_gfx` requires a
matching catalog entry.
"""

target_without_features = target_id.split(":", 1)[0]
arches = known_arches()
if target_without_features in arches:
return target_without_features
for arch in sorted(arches, key=len, reverse=True):
if target_without_features.startswith(f"{arch}-"):
return arch
match = re.match(r"^(gfx[0-9a-z]+)", target_without_features)
return match.group(1) if match else target_without_features


def compiler_target_from_target_id(target_id: str) -> str:
"""Derive the target name that the compile helpers pass to COMGR or hipcc.

Removes profile suffixes such as ``-strict`` using
:func:`base_arch_from_target_id`, but keeps features after ``:``.
For example, ``gfx1250-strict`` becomes ``gfx1250``, while
``gfx942:sramecc+:xnack-`` stays unchanged.

This only converts the string. COMGR or hipcc checks whether the target
and its features are supported when compilation runs.
"""

target_without_features, separator, features = target_id.partition(":")
base_arch = base_arch_from_target_id(target_id)
if target_without_features.startswith(f"{base_arch}-"):
target_without_features = base_arch
if separator:
return f"{target_without_features}:{features}"
return target_without_features


def arch_from_isa(isa: str) -> str:
"""Extract the gfx token from an isa triple like ``amdgcn-amd-amdhsa--gfx942``."""
return isa.rsplit("-", 1)[-1] if "-" in isa else isa
"""Extract a target ID from a COMGR ISA name, then derive its base architecture.
Comment thread
tenpercent marked this conversation as resolved.
Resolved

Combines :func:`target_id_from_isa` and :func:`base_arch_from_target_id`.
For example, ``amdgcn-amd-amdhsa--gfx942:xnack-`` becomes ``gfx942``.
"""

return base_arch_from_target_id(target_id_from_isa(isa))


def validate_arch(arch: Optional[str]) -> None:
Expand Down
Loading
Loading