Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
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
6 changes: 4 additions & 2 deletions dnn-providers/hip-kernel-provider/rocke/platform/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,10 @@ change must be made in **both** engines in the same change. Prove it:
```bash
python tools/check_byte_identity.py # build engine fresh + gate (llvm20)
ROCKE_LLVM_FLAVOR=llvm22 python tools/check_byte_identity.py # and llvm22
ROCKE_LLVM_FLAVOR=llvm23 python tools/check_byte_identity.py # and llvm23
```

A change is done only when the gate is GREEN for every family at both flavors.
A change is done only when the gate is GREEN for every family at every flavor.

## Build / test / run

Expand Down Expand Up @@ -316,6 +317,7 @@ dual-engine vs Python-only split.
|---|---|
| `ROCKE_BACKEND` | `cpp` (default) \| `python` \| `both` (differential assert) |
| `ROCKE_CPP_STRICT` | `1` = raise instead of silently falling back to Python when `rocke_engine` isn't built |
| `ROCKE_LLVM_FLAVOR` | `llvm20` \| `llvm22` (must match the ROCm `comgr` in use) |
| `ROCKE_LLVM_FLAVOR` | `llvm20` \| `llvm22` \| `llvm23` (must match the ROCm `comgr` in use: <7.2, 7.2-7.12, 7.13+) |
| `ROCKE_TEST_VERIFY_IR` | `1` = assemble emitted IR with `llvm-as` in `TestNewTargetIntrinsics`; needs an LLVM as new as the newest flavor |
| `ROCM_PATH` / `ROCM_HOME` | ROCm install root; `<root>/lib` is searched for `comgr`/HIP before the globbed `/opt/rocm*` trees |
| `ROCKE_COMGR_LIB` / `ROCKE_HIP_LIB` | explicit full path to `libamd_comgr` / `libamdhip64`; wins over all discovery |
Original file line number Diff line number Diff line change
Expand Up @@ -3259,6 +3259,22 @@ std::vector<std::string> gfx1201_wmma_gemm_verify(const py::dict& d, const std::
* involved. Every failure (parse or lower) is converted to a Python exception;
* the engine's extern "C" boundary never aborts/terminates.
* ------------------------------------------------------------------------ */

/* "'llvm20', 'llvm22', 'llvm23'" -- built from the engine's flavor ladder so
* the message cannot drift from what from_name() actually accepts. */
static std::string rocke_engine_flavor_list()
{
std::string out;
const int n = rocke_llvm_flavor_count();
for(int i = 0; i < n; ++i)
{
if(i)
out += (i + 1 == n) ? ", or " : ", ";
out += std::string("'") + rocke_llvm_flavor_at(i) + "'";
}
return out;
}

std::string lower_serialized_ir(const std::string& ir_text,
const std::string& arch,
const std::string& flavor)
Expand All @@ -3269,9 +3285,12 @@ std::string lower_serialized_ir(const std::string& ir_text,
}
const char* a = arch.empty() ? "gfx950" : arch.c_str();

/* flavor: "" => AUTO (resolve from env / ROCm version); "llvm20"/"llvm22"
* pin the intrinsic declaration shape. An unrecognised non-empty flavor is
* rejected so callers get the same hard error the Python lowerer raises. */
/* flavor: "" => AUTO (resolve from env / ROCm version); a named flavor
* pins the intrinsic declaration shape. An unrecognised non-empty flavor
* is rejected so callers get the same hard error the Python lowerer
* raises. The accepted set is read from the engine's ladder rather than
* restated here -- a hand-written list is what goes stale when a flavor is
* added. */
rocke_llvm_flavor_t fl = ROCKE_LLVM_FLAVOR_AUTO;
if(!flavor.empty())
{
Expand All @@ -3280,7 +3299,7 @@ std::string lower_serialized_ir(const std::string& ir_text,
{
throw std::runtime_error(
std::string("rocke_engine.lower_serialized_ir: unknown LLVM flavor '") + flavor
+ "' (expected 'llvm20' or 'llvm22')");
+ "' (expected one of " + rocke_engine_flavor_list() + ")");
}
}

Expand Down Expand Up @@ -3359,7 +3378,24 @@ PYBIND11_MODULE(rocke_engine, m)
"Parse serialized ck.dsl.ir/v1 text and lower it to AMDGPU LLVM IR "
"(.ll) text via the C++ engine. Family-agnostic; byte-identical to "
"the Python lowerer for the same serialized IR. flavor='' resolves "
"the LLVM flavor automatically; 'llvm20'/'llvm22' pin it.");
"the LLVM flavor automatically; a name from llvm_flavors() pins it.");

/* Exposes the engine's flavor ladder so a test can assert it still equals
* rocke.core.lower_llvm.LLVM_FLAVORS. Without a way to read the C++ list
* back, the two enumerations can drift into a flavor that lowers on one
* engine and is rejected on the other. */
m.def(
"llvm_flavors",
[]() {
std::vector<std::string> out;
const int n = rocke_llvm_flavor_count();
out.reserve((size_t)n);
for(int i = 0; i < n; ++i)
out.emplace_back(rocke_llvm_flavor_at(i));
return out;
},
"The LLVM flavors this engine accepts, oldest first. Must equal "
"rocke.core.lower_llvm.LLVM_FLAVORS.");

m.def("gemm_lower_llvm",
&gemm_lower_llvm,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -543,6 +543,8 @@ static const char* const rocke_opcode_names[ROCKE_OP__COUNT] = {
"tile.global_load_lds",
"tile.async_buffer_load_lds",
"tile.async_buffer_load_lds_addr",
"tile.buffer_load_lds_async",
"tile.global_load_async_to_lds",
"tile.buffer_rsrc",
"tile.buffer_load_f16",
"tile.buffer_load_vN_f16",
Expand Down Expand Up @@ -573,6 +575,18 @@ static const char* const rocke_opcode_names[ROCKE_OP__COUNT] = {
"tile.ds_bpermute",
"tile.ds_bpermute_b64",
"tile.ds_swizzle_xor",
"tile.ds_swizzle",
"tile.mov_dpp8",
"tile.wave_reduce",
"tile.readlane",
"tile.writelane",
"tile.permlane16",
"tile.permlane64",
"tile.alignbyte",
"tile.s_wqm",
"tile.av_load_b128",
"tile.av_store_b128",
"tile.s_alloc_vgpr",
"tile.mov_dpp",
"tile.permlane32_swap",
"tile.perm_b32",
Expand All @@ -588,6 +602,11 @@ static const char* const rocke_opcode_names[ROCKE_OP__COUNT] = {
"tile.sync_lds_only",
"tile.s_barrier_bare",
"tile.s_waitcnt",
"tile.s_wait_asynccnt",
"tile.asyncmark",
"tile.wait_asyncmark",
"tile.s_wait_event",
"tile.s_prefetch_inst",
"tile.s_setprio",
"tile.iglp_opt",
"tile.sched_barrier",
Expand Down Expand Up @@ -750,6 +769,8 @@ static const bool rocke_opcode_pure[ROCKE_OP__COUNT] = {
/* global_load_lds */ false,
/* async_buffer_load_lds */ false,
/* async_buffer_load_lds_addr */ false,
/* buffer_load_lds_async */ false,
/* global_load_async_to_lds */ false,
/* buffer_rsrc */ false,
/* buffer_load_f16 */ false,
/* buffer_load_vN_f16 */ false,
Expand Down Expand Up @@ -780,6 +801,18 @@ static const bool rocke_opcode_pure[ROCKE_OP__COUNT] = {
/* ds_bpermute */ true,
/* ds_bpermute_b64 */ false,
/* ds_swizzle_xor */ true,
/* ds_swizzle */ true,
/* mov_dpp8 */ true,
/* wave_reduce */ true,
/* readlane */ true,
/* writelane */ true,
/* permlane16 */ true,
/* permlane64 */ true,
/* alignbyte */ true,
/* s_wqm */ true,
/* av_load_b128 */ true,
/* av_store_b128 */ false,
/* s_alloc_vgpr */ false,
/* mov_dpp */ false,
/* permlane32_swap */ true,
/* perm_b32 */ true,
Expand All @@ -795,6 +828,11 @@ static const bool rocke_opcode_pure[ROCKE_OP__COUNT] = {
/* sync_lds_only */ false,
/* s_barrier_bare */ false,
/* s_waitcnt */ false,
/* s_wait_asynccnt */ false,
/* asyncmark */ false,
/* wait_asyncmark */ false,
/* s_wait_event */ false,
/* s_prefetch_inst */ false,
/* s_setprio */ false,
/* iglp_opt */ false,
/* sched_barrier */ false,
Expand Down
Loading
Loading