Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
be5609d
test(rocke): add emitted-IR validity gate (compile + link every corpu…
CongMa13 Sep 11, 2026
3181d32
fix(rocke): delete three dead intrinsic declares from both engines
CongMa13 Sep 11, 2026
88c0ec3
feat(rocke): generate the intrinsic arch-domain table by probing the …
CongMa13 Sep 16, 2026
7f8d805
feat(rocke): give the arch-domain table one column per LLVM flavor
CongMa13 Sep 11, 2026
aec2825
fix(rocke): retry crashed arch-domain probes serially before recordin…
CongMa13 Sep 16, 2026
7b422b8
fix(rocke): probe the arch domain at -O0 so the call survives to ISel
CongMa13 Sep 17, 2026
34cf8c4
test(rocke): gate the generated arch-domain artifact against drift
CongMa13 Sep 17, 2026
5ff5bc9
docs(rocke): record what S1 actually measured, and split the rest int…
CongMa13 Sep 17, 2026
c6a7b03
fix(rocke): let the arch-domain gate skip flavors this host cannot me…
CongMa13 Sep 17, 2026
010d36a
docs(rocke): record that the llvm20 column now also lags the decl table
CongMa13 Sep 17, 2026
7e225c8
Remove unused doc files
CongMa13 Sep 17, 2026
f9dc057
fix(rocke): record probe provenance and never let a hung probe read a…
CongMa13 Sep 18, 2026
65e62e9
refactor(rocke): size the byte-identity build from our CPU share, not…
CongMa13 Sep 21, 2026
c86d663
fix(rocke): stop the arch-domain check failing on the compiler build …
CongMa13 Sep 21, 2026
e946ecd
fix(rocke): stop recording an illegal probe operand as a missing inst…
CongMa13 Sep 21, 2026
e148bb1
feat(rocke): measure the third LLVM flavor, and learn the words it uses
CongMa13 Sep 22, 2026
69b8eba
fix(rocke): stop the gates reporting answers they never measured
CongMa13 Sep 30, 2026
3d5f93e
Merge branch 'develop' into users/congma/ck/rocke-arch-domain-table
CongMa13 Oct 3, 2026
ca0be61
fix(rocke): cover the xf32 MFMA decls in every arch-domain column
CongMa13 Oct 3, 2026
9282fb6
test(rocke): keep the runner tests off the IR-validity gate
CongMa13 Oct 3, 2026
0ea89b9
fix(rocke): mirror the fp8 kv "fnuz" name part into the C++ attention…
CongMa13 Oct 5, 2026
fd1df6e
Merge remote-tracking branch 'origin/develop' into users/congma/ck/ro…
CongMa13 Oct 5, 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
40 changes: 38 additions & 2 deletions dnn-providers/hip-kernel-provider/rocke/TESTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,42 @@ Key semantics:
([`fuzz_diff.py`](platform/tests/instances/differential/fuzz_diff.py)) feeds the
differential oracle with generated `(spec, arch)` inputs rather than a fixed list.

### 4.4 Is the emitted IR legal? (the toolchain gate)

§4.2 and §4.3 both compare rocKE's output against *another copy of rocKE's
output* — a golden sha, or the other engine. Neither asks the AMDGPU toolchain
whether the IR is valid at all, so an illegal construct that is emitted stably
and by both engines is green in both. The **emitted-IR validity gate**,
[`check_ir_validity.py`](platform/tools/check_ir_validity.py), asks the external
question: it lowers every case in the representative corpus
([`rocke_ir_parity_harness.cases()`](platform/tests/instances/rocke_ir_parity_harness.py),
the same corpus §4.2 hashes) and pushes each module through `clang` to a linked
hsaco.

Three design points, each of them load-bearing:

- **The oracle is a LINK, not a verify and not a codegen.** A `declare` for an
intrinsic that does not exist passes `opt -passes=verify`, *and* passes
`clang -S` — the backend silently treats the unknown `llvm.*` name as an
ordinary external function and emits a GOT-relative call. The undefined symbol
appears only when the relocatable is linked. Stopping anywhere earlier makes
the gate blind to the whole *fictional-intrinsic* bug class.
- **Every compile is a subprocess.** A backend failure is a
`report_fatal_error`, not an exception: it takes the process down. Compiling
in-process (via comgr, which is otherwise faster) means one bad module kills
the run and emits no report. The isolation is a correctness requirement, and
it makes the per-module diagnostic free.
- **Only the host's own LLVM flavor can be validated.** Modules lower at any
flavor, but there is no local compiler for the others; those report
`UNVALIDATED`, never green. On a host with no LLVM tools at all the gate
self-skips loudly — pass `--strict` to make that a failure instead.

Failures that are known and owned live in a `KNOWN_BAD` allowlist, same
convention and same rule as `KNOWN_VIOLATIONS` in
[`test_library_layering.py`](library/tests/test_library_layering.py): **it only
shrinks.** An entry that starts compiling is itself reported as a failure, so a
fix cannot leave dead weight behind.

---

## 5. Execution tiers & gating
Expand All @@ -332,13 +368,13 @@ Four distinct things run here; **do not conflate them**:

| Tier | What | Gated? |
|---|---|---|
| **1. Gate** | relative-path guard → byte-identity gate → pytest (`platform/tests`) → ctest | ✅ blocking |
| **1. Gate** | relative-path guard → byte-identity gate → emitted-IR validity gate → pytest (`platform/tests`) → ctest | ✅ blocking |
| **2. Diagnostics** | IR-canonical diff, fuzz diff, per-config golden check | ❌ opt-in |
| **3. GPU / numeric** | reference-oracle kernel-correctness lanes | ❌ skipped off-device |
| **4. Manual demos/tools** | hand-compiled CLIs / demos | ❌ |

**Two entrypoints with different environments and selection.** [`run_all.py`](platform/tests/run_all.py) is
the **developer** runner (guard → gate → pytest → ctest). **CI does not run
the **developer** runner (guard → gate → IR validity → pytest → ctest). **CI does not run
`run_all.py`** — it runs
**ctest** against the installed artifact, after the component script installs
the packaged wheels. Its registered pytest entries include the platform suite
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,10 @@ if(ROCKE_INSTALL_TESTS)
# Install the full pytest suite for installed/artifact test execution.
# Excludes: C/C++ parity emitters (compiled against rocke_core at build time),
# the differential harness (needs compiler + source), the WaveScope sidecar
# and LDS analyzer tests (load tools from the adjacent dsl_docs source tree).
# and LDS analyzer tests (load tools from the adjacent dsl_docs source tree),
# and the arch-domain artifact gate (imports tools/gen_arch_domain.py, which
# is not installed -- and an unresolvable import is a collection error that
# aborts the whole installed pytest session, not one skipped test).
# Include run_all.py: installed runner unit tests import it as a dependency.
# cmake-lint: disable=E1122
block()
Expand All @@ -403,7 +406,8 @@ if(ROCKE_INSTALL_TESTS)
PATTERN "*.cpp" EXCLUDE
PATTERN "differential" EXCLUDE
PATTERN "test_wavescope_sidecar.py" EXCLUDE
PATTERN "test_lds_analyzer.py" EXCLUDE)
PATTERN "test_lds_analyzer.py" EXCLUDE
PATTERN "test_arch_domain_artifact.py" EXCLUDE)

endblock()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -277,9 +277,6 @@ const rocke_ll_decl_t ROCKE_LL_INTRINSIC_DECLS[] = {
{"update.dpp.i32",
"declare i32 @llvm.amdgcn.update.dpp.i32(i32, i32, i32 immarg, i32 immarg, i32 immarg, i1 "
"immarg)"},
{"global.atomic.fadd.v2bf16",
"declare <2 x bfloat> @llvm.amdgcn.global.atomic.fadd.v2bf16.p1("
"ptr addrspace(1), <2 x bfloat>)"},
{"global.atomic.fadd.v2f16",
"declare <2 x half> @llvm.amdgcn.global.atomic.fadd.v2f16.p1("
"ptr addrspace(1), <2 x half>)"},
Expand Down Expand Up @@ -344,10 +341,6 @@ const rocke_ll_decl_t ROCKE_LL_INTRINSIC_DECLS[] = {
"declare <2 x float> @llvm.amdgcn.cvt.scalef32.pk.f32.fp8(i32, float, i1)"},
{"amdgcn.cvt.scalef32.pk.f32.bf8",
"declare <2 x float> @llvm.amdgcn.cvt.scalef32.pk.f32.bf8(i32, float, i1)"},
{"amdgcn.cvt.scalef32.pk.fp8.f32",
"declare i32 @llvm.amdgcn.cvt.scalef32.pk.fp8.f32(i32, <2 x float>, float, i1)"},
{"amdgcn.cvt.scalef32.pk.bf8.f32",
"declare i32 @llvm.amdgcn.cvt.scalef32.pk.bf8.f32(i32, <2 x float>, float, i1)"},
{"amdgcn.ds.swizzle", "declare i32 @llvm.amdgcn.ds.swizzle(i32, i32 immarg)"},
/* Not overloaded, so no name suffix, but the flags are immarg like every
* other permlane* flag pair. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,9 @@ static rocke_status_t
hkv_buf,
s->dtype ? s->dtype : "",
kv_buf,
/* Python emits "fnuz" under the *same* condition as the kv part,
* not under a format test, so it keys off kv_buf being non-empty. */
kv_buf[0] ? "fnuz" : "",
s->use_sinks ? "sinks" : "",
sw_buf,
s->has_softcap ? "softcap" : "",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,8 @@ int rocke_unified_attention_3d_tiled_spec_kernel_name(
const rocke_unified_attention_3d_tiled_spec_t* s, char* buf, size_t cap)
{
/* kernel_name_join("rocke_uattn3d_tiled_gfx942", d.., b.., h..kv.., seg..,
* dtype, kv<...> if kv_storage_dtype else "", "sinks" if use_sinks else "",
* dtype, kv<...> if kv_storage_dtype else "", "fnuz" if kv_storage_dtype
* else "", "sinks" if use_sinks else "",
* "sw<sw>" if sw>0 else "", "softcap" if has_softcap else "",
* "alibi" if use_alibi else "", "qqb" if use_qq_bias else "",
* "hoist" if use_invariant_hoist else "", "wkv" if use_wide_kv_load else "")
Expand Down Expand Up @@ -270,6 +271,9 @@ int rocke_unified_attention_3d_tiled_spec_kernel_name(
{
snprintf(kv_part, sizeof(kv_part), "kv%s", s->kv_storage_dtype);
parts[np++] = kv_part;
/* Python emits "fnuz" under the *same* condition as the kv part, not
* under a format test, so it is tagged here rather than separately. */
parts[np++] = "fnuz";
}
if(s->use_sinks)
{
Expand Down
Loading
Loading