|
#!/usr/bin/env python3 |
|
"""Finding 1: op_tile_global_load_async_to_lds uses the raw smem gname as the |
|
GEP base instead of the pool-relative base pointer. |
|
|
|
Calls the C++ engine DIRECTLY (bypassing backend.py's flavor gate, see finding 2). |
|
Env: ROCKE_SRC, ROCKE_BUILD (dir containing rocke_engine*.so) |
|
""" |
|
import os, sys |
|
SRC = os.environ["ROCKE_SRC"] |
|
BUILD = os.environ["ROCKE_BUILD"] |
|
sys.path.insert(0, BUILD); sys.path.insert(0, f"{SRC}/python") |
|
|
|
import rocke_engine |
|
from rocke.core.ir import IRBuilder, PtrType, F16 |
|
from rocke.core import ir_serialize |
|
from rocke.core.lower_llvm import lower_kernel_to_llvm as py_lower |
|
|
|
def build(): |
|
b = IRBuilder("f2_repro"); b.kernel.attrs["max_workgroup_size"] = 64 |
|
X = b.param("X", PtrType(F16, "global")); z = b.const_i32(0) |
|
a = b.smem_alloc(F16, [64, 8], name_hint="stageA") |
|
c = b.smem_alloc(F16, [64, 8], name_hint="stageB") |
|
b.smem_load_v4_f16(a, z, z) # keep A live -> offset 0 |
|
b.global_load_async_to_lds(X, z, c, [z, z], width_bytes=16) # async copy into B |
|
b.smem_load_v4_f16(c, z, z) # keep B live -> offset 1024 |
|
return b.kernel |
|
|
|
cpp_ll = rocke_engine.lower_serialized_ir(ir_serialize.serialize(build()), |
|
arch="gfx950", flavor="llvm23") |
|
py_ll = py_lower(build(), arch="gfx950", llvm_flavor="llvm23") |
|
open("f2_ENGINE_cpp.ll", "w").write(cpp_ll) |
|
open("f2_ENGINE_py.ll", "w").write(py_ll) |
|
|
|
print("byte-identical?", cpp_ll == py_ll) |
|
for tag, ll in (("CPP", cpp_ll), ("PY ", py_ll)): |
|
print(f"--- {tag} ---") |
|
for l in ll.splitlines(): |
|
if ("async_dst" in l and "getelementptr" in l) or (l.startswith("@") and "addrspace(3)" in l): |
|
print(" ", l.strip()) |
|
print("\nNow: opt -passes=verify f2_ENGINE_cpp.ll # expect: use of undefined value") |