Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
119 commits
Select commit Hold shift + click to select a range
93c9e0b
[stinkytofu] Add rocisa→logicalIR adapter with ROCISA_BACKEND dispatch
jimbochi Apr 23, 2026
5862e58
[stinkytofu] Add ROCISA_BACKEND dispatch to logicalIR adapter
jimbochi Apr 24, 2026
e167288
[stinkytofu] Add workaround for hw cap APIs
jimbochi Apr 27, 2026
702aea6
[stinkytofu] Add workaround hw caps table
jimbochi Apr 27, 2026
2e7b280
[stinkytofu] Support class-level static method on dummy shim
jimbochi Apr 28, 2026
4024549
[stinkytofu] Add RegisterPool and unit test to ir_adaptor
jimbochi May 5, 2026
036820e
[stinkytofu] minor cleanup: comments, license
jimbochi May 5, 2026
b43cb4b
[stinkytofu] Relocate ir_adaptor unit test next to python_module
jimbochi May 6, 2026
cfaa83e
[stinkytofu] Mirror new rocisa instructions after rebase and add MFMA…
jimbochi May 6, 2026
167da85
[stinkytofu] Mirror new EXECLO/EXECHI in ir_adaptor.container after r…
jimbochi May 6, 2026
dc7e55c
[stinkytofu] Implement SrdUpperValue workaround for gfx1250
jimbochi May 7, 2026
3ef8040
[stinkytofu] Workaround port of ArgumentLoader bookkeeping in ir_adap…
jimbochi May 7, 2026
057c029
[stinkytofu] Relocate ir_adaptor as standalone rocisa_stinkytofu_adap…
jimbochi May 13, 2026
473e93e
[stinkytofu] Replace SrdUpperValue gfx1250 stub with logicalIR binding
jimbochi May 15, 2026
b6ce949
[stinkytofu] Relocate rocisa_stinkytofu_adaptor as a sibling of tensi…
jimbochi May 15, 2026
92c0cb0
[stinkytofu] Add RegisterContainer/Holder shim with StinkyRegister bi…
jimbochi May 20, 2026
17b8233
[stinkytofu] Add GPR factories, ContinuousRegister, mgpr python binding
jimbochi May 21, 2026
22d760a
[stinkytofu] Add Container ABC, hardware tokens, and RegisterContaine…
jimbochi May 21, 2026
328eaac
[stinkytofu] Add MemTokenData to container adapter
jimbochi May 21, 2026
5b4b135
[stinkytofu] Add container modifier shims and glc/slc bit name helpers
jimbochi May 21, 2026
aaa71b5
[stinkytofu] Wire VMovB32 vertical slice through logical lowering pip…
jimbochi May 27, 2026
327bdbf
[stinkytofu] Fix Module/TextBlock parity gaps and move OutputOptions …
jimbochi Jun 2, 2026
ff6b856
[stinkytofu] Move remaining rocIsa singleton state to base module
jimbochi Jun 2, 2026
c757c48
[stinkytofu] Introduce Item base class for IR tree polymorphism
jimbochi Jun 2, 2026
f6c0af9
[stinkytofu] Rename "IR tree" -> "code composition components" in doc…
jimbochi Jun 2, 2026
57334c5
[stinkytofu] Promote ValueIf/ElseIf/Endif from dummy to real Item sub…
jimbochi Jun 3, 2026
cb1ca15
[stinkytofu] Promote ValueSet/RegSet from dummy to real Item subclasses
jimbochi Jun 3, 2026
2cbcdc7
[stinkytofu] Promote Label, LabelManager, and magicGenerator from dum…
jimbochi Jun 4, 2026
964bebe
[stinkytofu] Promote StructuredModule from dummy to real Module subclass
jimbochi Jun 5, 2026
177de6a
[stinkytofu] Promote Macro and MacroInstruction from dummy to real im…
jimbochi Jun 8, 2026
7435b79
[stinkytofu] Promote SignatureCodeMeta/SignatureBase from dummy to re…
jimbochi Jun 8, 2026
3b832e2
[stinkytofu] Promote KernelBody from dummy to real Item subclass
jimbochi Jun 8, 2026
529ad89
[stinkytofu] Replace SrdUpperValue gfx1250 primitives with createSrdU…
jimbochi Jun 8, 2026
e936057
[stinkytofu] Reorganize rocisa_stinkytofu_adaptor tests
jimbochi Jun 9, 2026
320ed45
[stinkytofu] Replace static caps with dynamic getHardwareCaps and TH/…
jimbochi Jun 9, 2026
e2b8a7b
[stinkytofu] Add gfx1250 th/nv/scope support to memory container modi…
jimbochi Jun 9, 2026
52650fb
[stinkytofu] Replace SignatureBase preloadKernArgs bool with numSgprP…
jimbochi Jun 9, 2026
0048a4d
[stinkytofu] Add dummy exports for develop-only instruction classes
jimbochi Jun 10, 2026
683ff28
[stinkytofu] Add missing countMFMA dummy export for KernelWriter
jimbochi Jun 10, 2026
2324ff4
[stinkytofu] Forward arch probe APIs to stinkytofu binding
jimbochi Jun 10, 2026
18209c6
[stinkytofu] Promote asmpass from dummy to real rocIsaPass pipeline
jimbochi Jun 11, 2026
ed00875
[stinkytofu] Replace toStinkyTofuModule dummy with logical-IR lowerin…
jimbochi Jun 11, 2026
ed7a73e
[stinkytofu] Doc: sync adaptor README and module docstrings
jimbochi Jun 11, 2026
a634228
[stinkytofu] Wire SMovB32/SMovB64 vertical slice through logical lowe…
jimbochi Jun 12, 2026
e413d1a
[stinkytofu] Wire SLoadB32–SLoadB512 through logical IR, adaptor, and…
jimbochi Jun 14, 2026
42f4207
[stinkytofu] Exclude test/tool dirs from import-time staleness checks
jimbochi Jun 15, 2026
e11f929
[stinkytofu] Wire SNop through logical IR, adaptor, and tablegen
jimbochi Jun 15, 2026
fba7b3c
[stinkytofu] Wire scalar ALU/shift/bitwise instructions through logic…
jimbochi Jun 16, 2026
9abc158
[stinkytofu] Wire SBarrier and scalar control instructions through lo…
jimbochi Jun 16, 2026
638b535
[stinkytofu] wire vector ALU instructions through logical IR adaptor
jimbochi Jun 16, 2026
55caa80
[stinkytofu] wire compare instructions (SCmp/VCmp/VCmpX) through logi…
jimbochi Jun 16, 2026
074aaa6
[stinkytofu] Wire vector unary/misc and scalar min/max instructions t…
jimbochi Jun 16, 2026
6b5e5f0
[stinkytofu] Wire conversion instructions (VCvt*/Scale) through logic…
jimbochi Jun 17, 2026
276c368
[stinkytofu] Wire memory instructions (Buffer/Flat/DS/Tensor) through…
jimbochi Jun 17, 2026
4af90ae
[stinkytofu] Wire MFMA/SMFMA/MXMFMA instructions through logical IR a…
jimbochi Jun 17, 2026
76a43d9
[stinkytofu] Wire branch/waitcnt/endpgm control-flow instructions thr…
jimbochi Jun 17, 2026
8ae71d3
[stinkytofu] Wire remaining ALU/ternary/unary/memory instructions cla…
jimbochi Jun 18, 2026
57c6017
[stinkytofu] Wire missing memory instruction variants (signed load/fl…
jimbochi Jun 19, 2026
b9c355f
[stinkytofu] Graduate private helper & composite instructions with Lo…
jimbochi Jun 19, 2026
2a3fa71
[stinkytofu] Graduate 24 Gfx1250-mapped dummy instructions with new L…
jimbochi Jun 21, 2026
e980342
[stinkytofu] Wire SStore/Atomic/Lane/DS/GlobalTR instructions through…
jimbochi Jun 22, 2026
f6547eb
[stinkytofu] Wire SWaitAlu/SchedulingFence as special-opcode instruct…
jimbochi Jun 22, 2026
1de6f3d
[stinkytofu] Implement module-level counting functions
jimbochi Jun 22, 2026
d89f497
[stinkytofu] Fix VNop adaptor to accept count parameter matching C++ …
jimbochi Jun 22, 2026
9e829a7
[stinkytofu] Graduate ArgumentLoader to emit real SLoadB* instructions
jimbochi Jun 22, 2026
cee099f
[stinkytofu] Implement math helper functions (divide/multiply/magic/bpe)
jimbochi Jun 22, 2026
a9db684
[stinkytofu] Implement branch helper functions (SLongBranch/BranchIfZ…
jimbochi Jun 22, 2026
98e5c29
[stinkytofu] Graduate all remaining dummy functions to real implement…
jimbochi Jun 22, 2026
337670a
[stinkytofu] Fix KeyError in text-variable pass by matching C++ missi…
jimbochi Jun 22, 2026
22df77a
[stinkytofu] Handle Container operands (VCC/EXEC) in _to_stinky_regis…
jimbochi Jun 22, 2026
e639fef
[stinkytofu] Fix VNop logical IR conversion to match stinkytofu signa…
jimbochi Jun 22, 2026
082e4a4
[stinkytofu] Skip symbolic reg_name for resolved registers and handle…
jimbochi Jun 23, 2026
238897c
[stinkytofu] Add DUMP_STINKY_MODULE debug instrumentation for cross-b…
jimbochi Jun 23, 2026
7cf0d28
[stinkytofu] Map wait instructions to gfx12+ opcodes via comment-mark…
jimbochi Jun 23, 2026
0592799
[stinkytofu] Expand v_cmpx_* into v_cmp_* + s_mov_b32 exec_lo via pos…
jimbochi Jun 23, 2026
45dc91c
[stinkytofu] Expand s_barrier into s_barrier_signal + s_barrier_wait …
jimbochi Jun 23, 2026
35e34d2
[stinkytofu] Fix wait-marker comment padding width from 45 to 51
jimbochi Jun 23, 2026
e640273
[stinkytofu] Insert vcc_lo carry operand into v_add_co/v_sub_co instr…
jimbochi Jun 23, 2026
001de04
[stinkytofu] Inject missing hardware caps and wire MFMAInstruction ac…
jimbochi Jun 24, 2026
171993a
[stinkytofu] Insert s_delay_alu scheduling hints via assembly post-pr…
jimbochi Jun 24, 2026
feb0b28
[stinkytofu] Fix ternary shift operand order for v_lshl_add/v_add_lsh…
jimbochi Jun 24, 2026
2018421
[stinkytofu] Preserve symbolic register names and emit .set directive…
jimbochi Jun 24, 2026
20b605d
[stinkytofu] Move .set directives from instruction body to wrapper la…
jimbochi Jun 25, 2026
0dcbb3f
[stinkytofu] Move debug dump before runOptimizationPipeline for pre-p…
jimbochi Jun 25, 2026
b10cf2d
[stinkytofu] Fix s_delay_alu insertion to match native C++ backend be…
jimbochi Jun 25, 2026
d0d243f
[stinkytofu] Add set_offset API to Register binding and emit VGPR MSB…
jimbochi Jun 26, 2026
ab61d0e
[stinkytofu] propagate DS/MUBUF modifiers through logical IR pipeline
jimbochi Jun 26, 2026
c5347a8
[stinkytofu] Emit .set directives inline with instructions via Logica…
jimbochi Jun 27, 2026
d5ed551
[stinkytofu] Emit labels inline with instructions via LogicalModule p…
jimbochi Jun 27, 2026
7eccfb3
[stinkytofu] Propagate VCndMaskB32 src2 (VCC/SGPR selector) through l…
jimbochi Jun 27, 2026
60f8fee
[stinkytofu] Propagate VOP3P op_sel modifier through logical IR pipeline
jimbochi Jun 27, 2026
b7b6605
[stinkytofu] Fix s_delay_alu insertion to match native C++ register d…
jimbochi Jun 28, 2026
3bbf8d0
[stinkytofu] Fix VNop to emit count copies in logical IR instead of one
jimbochi Jun 28, 2026
efcf2f8
[sintkytofu] align compositeToInstruction pass with native C++ implem…
jimbochi Jun 28, 2026
7efa9c9
[stinkytofu] implement removeDuplicatedFunction for activation dedup
jimbochi Jun 28, 2026
eb6628e
[stinkytofu] Implement buildGraph + removeDuplicateAssignment pass
jimbochi Jun 28, 2026
6695616
[stinkytofu] Fix s_delay_alu postprocess regex to strip cycle annotat…
jimbochi Jun 28, 2026
7744583
[stinkytofu] Add TextBlock support to emit inline comments via Logica…
jimbochi Jun 29, 2026
61f01dd
[stinkytofu] Align comment formatting and propagation with native C++…
jimbochi Jun 29, 2026
44f0d1b
[stinkytofu] Preserve insertion order of directives, labels, and text…
jimbochi Jun 29, 2026
228df8e
[stinkytofu] Emit Begin Kernel banner in adaptor signature to match n…
jimbochi Jun 29, 2026
6550771
[stinkytofu] Restrict delay_alu register tracking to CommonInstructio…
jimbochi Jun 29, 2026
a77b76e
[stinkytofu] Wire VMovRelsD2B32 through logical IR and adaptor for Co…
jimbochi Jun 29, 2026
5bef4f2
[stinkytofu] Wire VMovRelsD2B32, VPrngB32, and Pk8 scale-CVT instruct…
jimbochi Jun 29, 2026
97aecd2
[stinkytofu] Wire FlatAtomicDecU32 through logical IR and adaptor for…
jimbochi Jun 29, 2026
cab1234
[stinkytofu] Probe MaxWavesPerSimd dynamically in HardwareCaps instea…
jimbochi Jun 29, 2026
2d067c1
[stinkytofu] Wire gfx1250 asm probes and static regCaps into Hardware…
jimbochi Jun 29, 2026
f2dd618
[adaptor] Add maxVgpr to rocIsaPassResult mirroring native pass output
jimbochi Jun 29, 2026
422ad4a
[stinkytofu] Wire ModuleOptions (CloneList) through lower_logical_mod…
jimbochi Jun 29, 2026
28ed61b
[stinkytofu] Exclude python_module/ from rocisa staleness check for _…
jimbochi Jun 30, 2026
843fdef
[stinkytofu] Propagate temporal hint (th) and isStore through set_mub…
jimbochi Jun 30, 2026
384bda0
[stinkytofu] Propagate instruction group markers from Module tree to …
jimbochi Jul 3, 2026
c990a43
[stinkytofu] Skip adaptor SDelayAlu emission and attach MFMAModifiers…
jimbochi Jul 3, 2026
0e1aafb
[stinkytofu] Fix VGPR MSB encoding in adaptor: align store operand ma…
jimbochi Jul 3, 2026
4e797cf
[stinkytofu] Fix VCndMaskB32 test call to match updated 4-operand sig…
jimbochi Jul 3, 2026
5517f44
[stinkytofu] Wire VDualFMACF32 dual-issue VOPD instruction for adapto…
jimbochi Jul 3, 2026
6caa5e7
[stinkytofu] Wire Global load/store instructions (GlobalLoadB*, Globa…
jimbochi Jul 3, 2026
4596502
[stinkytofu] Add missing GlobalStoreB8, GlobalStoreB16, GlobalStoreD1…
jimbochi Jul 3, 2026
3cc2b9d
[stinkytofu] Add .v4i32 suffix to raw buffer intrinsics for new LLVM …
jimbochi Jul 3, 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
12 changes: 12 additions & 0 deletions projects/hipblaslt/tensilelite/Tensile/KernelWriter.py
Original file line number Diff line number Diff line change
Expand Up @@ -6651,6 +6651,18 @@ def _restoreNtabState():
t1a_end = time.perf_counter()
print2(f"StinkyTofu (1a) toStinkyTofuModule: {t1a_end - t1a_start:.4f}s")

# --- DEBUG: dump StinkyAsmModule BEFORE optimization pipeline ---
# Compares the two paths' logical→asm lowering output before shared passes run.
if os.environ.get("DUMP_STINKY_MODULE"):
_dump_dir = os.environ.get("DUMP_STINKY_MODULE", "/tmp/stinky_dump")
os.makedirs(_dump_dir, exist_ok=True)
_backend_tag = os.environ.get("ROCISA_BACKEND", "native")
_dump_asm = stModule.emitAssembly()
_dump_path = os.path.join(_dump_dir, f"stmodule_{_backend_tag}.s")
with open(_dump_path, "w") as _df:
_df.write(_dump_asm)
print2(f"StinkyTofu DEBUG: dumped pre-pipeline module ({len(_dump_asm)} chars) -> {_dump_path}")

# Run pipeline — builder handles O0 internally (skips optimization,
# still runs required passes like InsertVgprMsb)
t1b_start = time.perf_counter()
Expand Down
20 changes: 10 additions & 10 deletions projects/hipblaslt/tensilelite/Tensile/Source/memory_gfx.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,35 +161,35 @@ __device__ char
llvm_amdgcn_raw_buffer_load_i8(int32x4_t buffer_resource,
uint32_t voffset,
uint32_t soffset,
int32_t cache_op) __asm("llvm.amdgcn.raw.buffer.load.i8");
int32_t cache_op) __asm("llvm.amdgcn.raw.buffer.load.i8.v4i32");

// 2 bytes
__device__ float16_t
llvm_amdgcn_raw_buffer_load_f16(int32x4_t buffer_resource,
uint32_t voffset,
uint32_t soffset,
int32_t cache_op) __asm("llvm.amdgcn.raw.buffer.load.f16");
int32_t cache_op) __asm("llvm.amdgcn.raw.buffer.load.f16.v4i32");

// 4 bytes
__device__ float32_t
llvm_amdgcn_raw_buffer_load_f32(int32x4_t buffer_resource,
uint32_t voffset,
uint32_t soffset,
int32_t cache_op) __asm("llvm.amdgcn.raw.buffer.load.f32");
int32_t cache_op) __asm("llvm.amdgcn.raw.buffer.load.f32.v4i32");

// 8 bytes
__device__ float32x2_t
llvm_amdgcn_raw_buffer_load_f32x2(int32x4_t buffer_resource,
uint32_t voffset,
uint32_t soffset,
int32_t cache_op) __asm("llvm.amdgcn.raw.buffer.load.v2f32");
int32_t cache_op) __asm("llvm.amdgcn.raw.buffer.load.v2f32.v4i32");

// 16 bytes
__device__ float32x4_t
llvm_amdgcn_raw_buffer_load_f32x4(int32x4_t buffer_resource,
uint32_t voffset,
uint32_t soffset,
int32_t cache_op) __asm("llvm.amdgcn.raw.buffer.load.v4f32");
int32_t cache_op) __asm("llvm.amdgcn.raw.buffer.load.v4f32.v4i32");

// 4 bytes
__device__ int32_t
Expand Down Expand Up @@ -219,39 +219,39 @@ __device__ void
int32x4_t buffer_resource,
uint32_t voffset,
uint32_t soffset,
int32_t cache_op) __asm("llvm.amdgcn.raw.buffer.store.i8");
int32_t cache_op) __asm("llvm.amdgcn.raw.buffer.store.i8.v4i32");

// 2 bytes
__device__ void
llvm_amdgcn_raw_buffer_store_f16(float16_t data,
int32x4_t buffer_resource,
uint32_t voffset,
uint32_t soffset,
int32_t cache_op) __asm("llvm.amdgcn.raw.buffer.store.f16");
int32_t cache_op) __asm("llvm.amdgcn.raw.buffer.store.f16.v4i32");

// 4 bytes
__device__ void
llvm_amdgcn_raw_buffer_store_f32(float32_t data,
int32x4_t buffer_resource,
uint32_t voffset,
uint32_t soffset,
int32_t cache_op) __asm("llvm.amdgcn.raw.buffer.store.f32");
int32_t cache_op) __asm("llvm.amdgcn.raw.buffer.store.f32.v4i32");

// 8 bytes
__device__ void llvm_amdgcn_raw_buffer_store_f32x2(
float32x2_t data,
int32x4_t buffer_resource,
uint32_t voffset,
uint32_t soffset,
int32_t cache_op) __asm("llvm.amdgcn.raw.buffer.store.v2f32");
int32_t cache_op) __asm("llvm.amdgcn.raw.buffer.store.v2f32.v4i32");

// 16 bytes
__device__ void llvm_amdgcn_raw_buffer_store_f32x4(
float32x4_t data,
int32x4_t buffer_resource,
uint32_t voffset,
uint32_t soffset,
int32_t cache_op) __asm("llvm.amdgcn.raw.buffer.store.v4f32");
int32_t cache_op) __asm("llvm.amdgcn.raw.buffer.store.v4f32.v4i32");

////////////////////////////////////////////////////////////////////////////////////////////////////

Expand Down
62 changes: 58 additions & 4 deletions projects/hipblaslt/tensilelite/rocisa/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -133,13 +133,21 @@ if(HIPBLASLT_BUNDLE_PYTHON_DEPS OR ROCISA_STANDALONE)
if(NOT TARGET stinkytofu::stinkytofu)
find_package(stinkytofu QUIET)
if(NOT stinkytofu_FOUND)
set(_stinkytofu_sibling "${CMAKE_CURRENT_SOURCE_DIR}/../../../../shared/stinkytofu")
if(IS_DIRECTORY "${_stinkytofu_sibling}")
set(STINKYTOFU_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../../shared/stinkytofu")
if(EXISTS "${STINKYTOFU_DIR}/CMakeLists.txt")
set(BUILD_SHARED_LIBS ON)
set(STINKYTOFU_ENABLE_WERROR ON)
add_subdirectory("${_stinkytofu_sibling}" stinkytofu EXCLUDE_FROM_ALL)

# Force StinkyTofu Python bindings ON because the rocisa->stinkytofu
# adapter relies on the _stinkytofu.so nanobind module.
set(STINKYTOFU_BUILD_PYTHON ON CACHE BOOL
"Build StinkyTofu Python bindings (required by ROCISA_BACKEND=stinkytofu adapter)"
FORCE)

add_subdirectory("${STINKYTOFU_DIR}" stinkytofu EXCLUDE_FROM_ALL)
set(_stinkytofu_from_subdirectory TRUE)
else()
message(FATAL_ERROR "stinkytofu not found via find_package or sibling directory")
message(FATAL_ERROR "stinkytofu not found via find_package or sibling directory: ${STINKYTOFU_DIR}")
endif()
endif()
endif()
Expand Down Expand Up @@ -235,6 +243,52 @@ if(HIPBLASLT_BUNDLE_PYTHON_DEPS OR ROCISA_STANDALONE)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/rocisa/_build_info.py" DESTINATION rocisa)
endif()

# ---------------------------------------------------------------------
# Sibling staging for the stinkytofu Python package.
# ---------------------------------------------------------------------
if(TARGET stinkytofu_python)
add_dependencies(_rocisa stinkytofu_python)

set_target_properties(stinkytofu_python PROPERTIES
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/stinkytofu"
BUILD_RPATH "$ORIGIN"
INSTALL_RPATH "$ORIGIN"
)

set(STINKYTOFU_TOP_DIR "${STINKYTOFU_DIR}")
configure_file(
"${STINKYTOFU_DIR}/python_module/stinkytofu/__init__.py"
"${CMAKE_CURRENT_BINARY_DIR}/stinkytofu/__init__.py"
COPYONLY
)
configure_file(
"${STINKYTOFU_DIR}/python_module/stinkytofu/_build_info.py.in"
"${CMAKE_CURRENT_BINARY_DIR}/stinkytofu/_build_info.py"
@ONLY
)

# -----------------------------------------------------------------
# intrinsics.st.bc — runtime bitcode loaded by IntrinsicRegistry
# -----------------------------------------------------------------
if(TARGET intrinsics_compiled)
add_dependencies(_rocisa intrinsics_compiled)

set(_intrinsics_bc_src "${CMAKE_BINARY_DIR}/intrinsics.st.bc")
set(_intrinsics_bc_dst "${CMAKE_CURRENT_BINARY_DIR}/stinkytofu/intrinsics.st.bc")
add_custom_command(
OUTPUT "${_intrinsics_bc_dst}"
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${_intrinsics_bc_src}" "${_intrinsics_bc_dst}"
DEPENDS intrinsics_compiled "${_intrinsics_bc_src}"
COMMENT "Staging intrinsics.st.bc next to _stinkytofu.so"
VERBATIM
)
add_custom_target(rocisa_stage_intrinsics ALL
DEPENDS "${_intrinsics_bc_dst}")
add_dependencies(_rocisa rocisa_stage_intrinsics)
endif()
endif()

if(ROCISA_STANDALONE)
# scikit-build-core wheel install rules: place _rocisa and __init__.py into the
# rocisa/ package directory in the wheel.
Expand Down
189 changes: 140 additions & 49 deletions projects/hipblaslt/tensilelite/rocisa/rocisa/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Copyright © Advanced Micro Devices, Inc., or its affiliates.
# SPDX-License-Identifier: MIT

import os
import sys
import types

Expand All @@ -14,26 +15,83 @@
)
del _Path

from ._rocisa import *
from . import _rocisa

# Register nanobind submodules under the rocisa.* namespace so that
# `from rocisa.enum import X` and `import rocisa.instruction as ri` work.
for _name, _obj in vars(_rocisa).items():
if isinstance(_obj, types.ModuleType) and not _name.startswith("_"):
sys.modules.setdefault(f"rocisa.{_name}", _obj)

# Staleness check: only active in source builds.
# Pre-built packages (wheels, apt) lack _build_info.py — the import is
# silently skipped. Catching ImportError (not just ModuleNotFoundError)
# because Python 3.10 raises ImportError for missing relative submodules.
# The intentional staleness ImportError is raised outside the try/except
# so it is never swallowed.
_bi = None
try:
from . import _build_info as _bi
except ImportError:
pass # Pre-built package — no source tree, skip check
# ---------------------------------------------------------------------------
# Backend dispatch
# ---------------------------------------------------------------------------
# ``ROCISA_BACKEND=stinkytofu`` redirects ``import rocisa`` to the
# ``rocisa_stinkytofu_adaptor`` shim (a rocisa-shaped facade backed by the
# stinkytofu Python binding ``_stinkytofu.so``). Anything else (or unset)
# keeps the original nanobind bindings in ``_rocisa``.

_BACKEND = os.environ.get("ROCISA_BACKEND", "").strip().lower()

_ADAPTER_PKG = "rocisa_stinkytofu_adaptor"


def _load_stinkytofu_adapter() -> bool:
"""Try to install the rocisa_stinkytofu_adaptor as the ``rocisa`` module.

Returns True iff we successfully rewired sys.modules; on any failure
we fall back to the nanobind bindings silently (the caller decides
whether that is acceptable).
"""

# Locate ``<repo_root>/projects/hipblaslt/tensilelite/rocisa_stinkytofu_adaptor``
# by walking up from this file until we find an ancestor whose basename
# is ``projects``; the adapter then lives at
# ``<that_parent>/projects/hipblaslt/tensilelite/<_ADAPTER_PKG>/``.
#
# The adapter is a sibling of ``tensilelite/rocisa/`` on purpose — it is
# a *consumer* of the stinkytofu Python binding (a tensilelite-internal
# alternative backend), not a piece of ``shared/stinkytofu/`` itself.
# Sibling-of-rocisa keeps ``ROCISA_BACKEND=stinkytofu`` purely a
# tensilelite concern.
#
# Works for both the source tree (``<repo>/projects/hipblaslt/
# tensilelite/rocisa/rocisa/__init__.py``) and CMake-staged copies
# under ``<repo>/projects/hipblaslt/tensilelite/<build_dir>/tensilelite/
# rocisa/rocisa/__init__.py`` because in either case walking up from
# ``__file__`` eventually hits the ``projects`` directory.
repo_root = None
cur = os.path.dirname(os.path.abspath(__file__))
adapter_rel = os.path.join("projects", "hipblaslt", "tensilelite", _ADAPTER_PKG)
while True:
parent = os.path.dirname(cur)
if parent == cur: # reached filesystem root
break
if os.path.basename(cur) == "projects":
candidate = parent
if os.path.isdir(os.path.join(candidate, adapter_rel)):
repo_root = candidate
break
cur = parent
if repo_root is None:
return False
adapter_parent = os.path.join(repo_root, adapter_rel)

if not os.path.isdir(os.path.join(adapter_parent, _ADAPTER_PKG)):
return False

if adapter_parent not in sys.path:
sys.path.insert(0, adapter_parent)

try:
import rocisa_stinkytofu_adaptor as _adapter # noqa: F401
except Exception:
return False

# Install the adapter as ``rocisa`` and re-export each
# ``rocisa_stinkytofu_adaptor.*`` submodule under ``rocisa.*`` in
# ``sys.modules``.
sys.modules["rocisa"] = _adapter
_prefix = f"{_ADAPTER_PKG}."
for _name, _obj in vars(_adapter).items():
if isinstance(_obj, types.ModuleType) and _obj.__name__.startswith(_prefix):
short = _obj.__name__[len(_prefix):]
sys.modules[f"rocisa.{short}"] = _obj

return True


def _find_stale_sources(so_path, source_roots, build_dir):
"""Return source files newer than so_path, excluding files under build_dir.
Expand All @@ -54,37 +112,70 @@ def _find_stale_sources(so_path, source_roots, build_dir):
return stale


if _bi is not None:
from pathlib import Path
if _BACKEND == "stinkytofu" and _load_stinkytofu_adapter():
# stinkytofu adapter active; wiring done inside _load_stinkytofu_adapter.
pass
else:
# Default path: original nanobind bindings.
from ._rocisa import * # noqa: F401,F403
from . import _rocisa

# Register nanobind submodules under the rocisa.* namespace so that
# `from rocisa.enum import X` and `import rocisa.instruction as ri` work.
for _name, _obj in vars(_rocisa).items():
if isinstance(_obj, types.ModuleType) and not _name.startswith("_"):
sys.modules.setdefault(f"rocisa.{_name}", _obj)

# Staleness check: only active in source builds.
# Pre-built packages (wheels, apt) lack _build_info.py — the import is
# silently skipped. Catching ImportError (not just ModuleNotFoundError)
# because Python 3.10 raises ImportError for missing relative submodules.
# The intentional staleness ImportError is raised outside the try/except
# so it is never swallowed.
_bi = None
try:
from . import _build_info as _bi
except ImportError:
pass # Pre-built package — no source tree, skip check

if _bi is not None:
from pathlib import Path

_so = Path(_rocisa.__file__)
# Scan rocisa sources and stinkytofu asm-IR sources (since _rocisa.so
# links libstinkytofu.so for the toStinkyTofuModule / emitAssembly path).
# Both roots are populated by CMake; an empty one signals a malformed
# _build_info.py. Warn (rather than scan Path("") == the CWD) and skip it,
# so a regression surfaces instead of silently disabling the check.
# Excluded from the stinkytofu scan:
# - tests/ — test code is never compiled into .so
# - python_module/ — only compiled into _stinkytofu.so (Python bindings)
# - src/ir/logical — logical IR is only used by _stinkytofu.so (left
# path); _rocisa.so never touches logical modules.
_roots = []
for _name, _root in (("rocisa", _bi.SOURCE_ROOT), ("stinkytofu", _bi.STINKYTOFU_SOURCE_ROOT)):
if _root:
_roots.append(Path(_root))
else:
import warnings

_so = Path(_rocisa.__file__)
# Scan rocisa sources and, while stinkytofu is compiled into _rocisa.so,
# stinkytofu sources too. STINKYTOFU_SOURCE_ROOT is removed once rocisa
# and stinkytofu are loaded independently.
# Both roots are populated by CMake; an empty one signals a malformed
# _build_info.py. Warn (rather than scan Path("") == the CWD) and skip it,
# so a regression surfaces instead of silently disabling the check.
_roots = []
for _name, _root in (("rocisa", _bi.SOURCE_ROOT), ("stinkytofu", _bi.STINKYTOFU_SOURCE_ROOT)):
if _root:
_roots.append(Path(_root))
else:
import warnings

warnings.warn(
f"rocisa staleness check: {_name} source root is unset in "
f"_build_info.py; skipping it. Rebuild with: invoke rocisa",
stacklevel=2,
warnings.warn(
f"rocisa staleness check: {_name} source root is unset in "
f"_build_info.py; skipping it. Rebuild with: invoke rocisa",
stacklevel=2,
)
_st_root = Path(_bi.STINKYTOFU_SOURCE_ROOT) if _bi.STINKYTOFU_SOURCE_ROOT else None
_st_skip = {_st_root / "tests", _st_root / "src" / "ir" / "logical", _st_root / "python_module"} if _st_root else set()
_all_stale = _find_stale_sources(_so, _roots, _bi.BUILD_DIR)
_stale = [s for s in _all_stale if not any(Path(s).is_relative_to(sk) for sk in _st_skip)]
if _stale:
_preview = _stale[:3] + (["..."] if len(_stale) > 3 else [])
raise ImportError(
"rocisa C++ sources are newer than the built _rocisa.so — bindings are stale.\n"
f" Modified: {', '.join(_preview)}\n"
" Rebuild: invoke rocisa"
)
_stale = _find_stale_sources(_so, _roots, _bi.BUILD_DIR)
if _stale:
_preview = _stale[:3] + (["..."] if len(_stale) > 3 else [])
raise ImportError(
"rocisa C++ sources are newer than the built _rocisa.so — bindings are stale.\n"
f" Modified: {', '.join(_preview)}\n"
" Rebuild: invoke rocisa"
)
del _bi, _so, _stale, _roots, _name, _root, Path
del _bi, _so, _stale, _all_stale, _roots, _name, _root, _st_root, _st_skip, Path


def hasStinkyTofuBackend() -> bool:
Expand Down
Loading
Loading