Hiya,
@FileDelta asked in #112 what's going on with the runtimes, and the honest answer turned out to be "more than I realised". So I went through the tree properly. This is what's actually there and what I'm going to do about it.
The short version: the layout is a fossil of what needed to compile, not of a design. Makefile:20 puts every backend directory on every translation unit's include path, so nothing structurally stops any file from including any other. Most of the tree ignores that. A handful of places didn't, and those are the mess. Less archaeology, more of a landfill with good intentions.
The runtimes
The confusing part is that the split isn't by vendor. It's host vs device, and the two directories are named almost identically while meaning opposite things. src/runtime/ and runtime/. I did that. There's nobody else to blame.
src/runtime/bc_runtime.c — AMD HSA host launcher, dlopens libhsa
src/nvidia/nv_rt.c — NVIDIA host launcher, dlopens nvcuda/libcuda
src/runtime/bc_abend.c — host-side crash diagnostics, welded to the AMD launcher
runtime/soft_fp.c — device side, fp32 for the Tensix RV32IM baby cores
runtime/sysprint.c — both halves in one file, kernels emit records, host drains them
src/tensix/rt_args.h — not runtime at all, it's a compiler/launcher ABI contract
@FileDelta also spotted that nv_rt looks unused. It's worse than unused. It's in no Makefile target at all: not SOURCES, not TSRC, not COBJS. make has never compiled it. tests/tnv_rt.c exists but isn't in TSRC either, so trunner never runs it. It's been sitting there like a gym membership. It does still build clean under the full warning set, which is the only reason I'm not more embarrassed.
bc_runtime.c is in the same position, only bc_abend.o reaches COBJS. And -Iruntime is in TCFLAGS but not CFLAGS, so kath itself can't resolve soft_fp.h or sysprint.h.
Plan: runtime/host/{hsa,cuda}, runtime/device, runtime/include/booth, and src/ becomes the compiler and nothing else.
Layering
Five edges point the wrong way.
ir/bir_lower.c:2 includes ../amd_target_defs.h and genuinely uses it at bir_lower.c:792, because lowering warpSize needs the AMD wave size during BIR construction. That's a real requirement, but it does mean AMD specifics live in the target-agnostic layer. It's also why that header sits at the top of src/ rather than in src/amdgpu/, which is less a design decision and more a witness relocation programme.
fe/sema.c:2 includes the same header and uses nothing from it. Vestigial, easy delete.
ir/bir_lower.h:5-6 include parser.h and sema.h, so frontend types leak upward into anything that includes IR lowering.
tdf and tensix are circular. tdf.h:6 includes tensix's rv_buf.h; tensix/rv_isel.h:7 includes tdf.h purely for BC_ERR_TDF. They've been going round in circles, which I suppose is on-brand for a dataflow graph. Because main.c includes tdf.h, the AMD and NVIDIA builds transitively pull a Tensix header.
src/runtime/bc_abend.c:18 includes ../fe/bc_err.h, so the host runtime depends on the compiler frontend. This is the one actually blocking the runtime split.
Worth saying: there is no backend-to-backend coupling anywhere. All seven backends depend on bir.h and nothing else from src/ir/. That part held up fine, so it's not all bad news.
Dead and unreachable
amdgpu/ra_ssa.h has zero includers. Its prototype is duplicated at amdgpu.h:496 and that's the one in use. The header is a spare key to a house nobody visits.
tests/test_bir.c:1 includes ../src/bir.h, which doesn't exist. Presumably where it lived before ir/ did. Not in TSRC, so it never compiles, so it never complains.
sizecheck.c in the repo root includes nvidia.h and is in no Makefile target.
amdgpu/emit.c.new (130KB) and nvidia/nv_ra.c.bak aren't in the build. The newest thing about .new is the filename.
rv_isel_module at rv_isel.c:1391 has no caller in src/, only tests.
- TDF's multi-region lowering is unreachable:
--tdf-fission returns at main.c:151, before td_lower at :157.
Bugs this turned up
kath --triton --cpu foo.py -o x.o prints an error, emits nothing, and exits 0. It fails successfully. --cpu is in want_backend at main.c:731-733 but missing from the gate at main.c:720-722. That's the exact path examples/cpu_launch_matmul.c documents as the headline demo. It went unnoticed because examples/*.c have no Makefile rule, so none of them are ever built. Schrödinger's demo: it works right up until someone opens the box.
Error codes collide. BC_ERR_NVIDIA and BC_ERR_METAL are both -8 and both headers are included in main.c, so -8 is doing the work of two. BC_ERR_PREPROC, BC_ERR_LOWER and BC_ERR_VERIFY are all -5. BC_ERR_SEMA and BC_ERR_AMDGPU are both -6.
Backends aren't mutually exclusive either. --amdgpu --nvidia-ptx --metal runs all three off one BIR and they all collide on -o. Three backends, one output path, no survivors.
Stale docs, including mine
main.c:688-698 says the Triton frontend stops at the lexer and that parser, sema and lowering are stubs. They're fully wired at main.c:720-801. The comment is describing a compiler that hasn't existed for a while.
--help calls --metal a stub. It isn't, it's 832 lines of real BIR→MSL lowering. --intel-spirv is the actual stub at 52 lines. I libelled my own backend.
--no-sroa, --bkhit and --snap are parsed but missing from usage().
Order I'm going in
- Wire
nv_rt and the examples into the build, unmoved, so there's a signal before anything shifts.
- Fix the
--triton --cpu gate and the exit code.
- Move the runtime into host/device.
- Cut the layering edges, starting with
bc_abend → fe.
- Error code collisions and the stale comments.
- Then the packaging work this all came out of:
make install, and a CMake package so people can drop Booth into their own build.
Happy to take help on any of it. Thanks @FileDelta for the poke, it turned over a lot more than you'd have guessed.
Hiya,
@FileDelta asked in #112 what's going on with the runtimes, and the honest answer turned out to be "more than I realised". So I went through the tree properly. This is what's actually there and what I'm going to do about it.
The short version: the layout is a fossil of what needed to compile, not of a design.
Makefile:20puts every backend directory on every translation unit's include path, so nothing structurally stops any file from including any other. Most of the tree ignores that. A handful of places didn't, and those are the mess. Less archaeology, more of a landfill with good intentions.The runtimes
The confusing part is that the split isn't by vendor. It's host vs device, and the two directories are named almost identically while meaning opposite things.
src/runtime/andruntime/. I did that. There's nobody else to blame.src/runtime/bc_runtime.c— AMD HSA host launcher, dlopens libhsasrc/nvidia/nv_rt.c— NVIDIA host launcher, dlopens nvcuda/libcudasrc/runtime/bc_abend.c— host-side crash diagnostics, welded to the AMD launcherruntime/soft_fp.c— device side, fp32 for the Tensix RV32IM baby coresruntime/sysprint.c— both halves in one file, kernels emit records, host drains themsrc/tensix/rt_args.h— not runtime at all, it's a compiler/launcher ABI contract@FileDelta also spotted that
nv_rtlooks unused. It's worse than unused. It's in no Makefile target at all: notSOURCES, notTSRC, notCOBJS.makehas never compiled it.tests/tnv_rt.cexists but isn't inTSRCeither, sotrunnernever runs it. It's been sitting there like a gym membership. It does still build clean under the full warning set, which is the only reason I'm not more embarrassed.bc_runtime.cis in the same position, onlybc_abend.oreachesCOBJS. And-Iruntimeis inTCFLAGSbut notCFLAGS, so kath itself can't resolvesoft_fp.horsysprint.h.Plan:
runtime/host/{hsa,cuda},runtime/device,runtime/include/booth, andsrc/becomes the compiler and nothing else.Layering
Five edges point the wrong way.
ir/bir_lower.c:2includes../amd_target_defs.hand genuinely uses it atbir_lower.c:792, because loweringwarpSizeneeds the AMD wave size during BIR construction. That's a real requirement, but it does mean AMD specifics live in the target-agnostic layer. It's also why that header sits at the top ofsrc/rather than insrc/amdgpu/, which is less a design decision and more a witness relocation programme.fe/sema.c:2includes the same header and uses nothing from it. Vestigial, easy delete.ir/bir_lower.h:5-6includeparser.handsema.h, so frontend types leak upward into anything that includes IR lowering.tdfandtensixare circular.tdf.h:6includes tensix'srv_buf.h;tensix/rv_isel.h:7includestdf.hpurely forBC_ERR_TDF. They've been going round in circles, which I suppose is on-brand for a dataflow graph. Becausemain.cincludestdf.h, the AMD and NVIDIA builds transitively pull a Tensix header.src/runtime/bc_abend.c:18includes../fe/bc_err.h, so the host runtime depends on the compiler frontend. This is the one actually blocking the runtime split.Worth saying: there is no backend-to-backend coupling anywhere. All seven backends depend on
bir.hand nothing else fromsrc/ir/. That part held up fine, so it's not all bad news.Dead and unreachable
amdgpu/ra_ssa.hhas zero includers. Its prototype is duplicated atamdgpu.h:496and that's the one in use. The header is a spare key to a house nobody visits.tests/test_bir.c:1includes../src/bir.h, which doesn't exist. Presumably where it lived beforeir/did. Not inTSRC, so it never compiles, so it never complains.sizecheck.cin the repo root includesnvidia.hand is in no Makefile target.amdgpu/emit.c.new(130KB) andnvidia/nv_ra.c.bakaren't in the build. The newest thing about.newis the filename.rv_isel_moduleatrv_isel.c:1391has no caller insrc/, only tests.--tdf-fissionreturns atmain.c:151, beforetd_lowerat:157.Bugs this turned up
kath --triton --cpu foo.py -o x.oprints an error, emits nothing, and exits 0. It fails successfully.--cpuis inwant_backendatmain.c:731-733but missing from the gate atmain.c:720-722. That's the exact pathexamples/cpu_launch_matmul.cdocuments as the headline demo. It went unnoticed becauseexamples/*.chave no Makefile rule, so none of them are ever built. Schrödinger's demo: it works right up until someone opens the box.Error codes collide.
BC_ERR_NVIDIAandBC_ERR_METALare both -8 and both headers are included inmain.c, so -8 is doing the work of two.BC_ERR_PREPROC,BC_ERR_LOWERandBC_ERR_VERIFYare all -5.BC_ERR_SEMAandBC_ERR_AMDGPUare both -6.Backends aren't mutually exclusive either.
--amdgpu --nvidia-ptx --metalruns all three off one BIR and they all collide on-o. Three backends, one output path, no survivors.Stale docs, including mine
main.c:688-698says the Triton frontend stops at the lexer and that parser, sema and lowering are stubs. They're fully wired atmain.c:720-801. The comment is describing a compiler that hasn't existed for a while.--helpcalls--metala stub. It isn't, it's 832 lines of real BIR→MSL lowering.--intel-spirvis the actual stub at 52 lines. I libelled my own backend.--no-sroa,--bkhitand--snapare parsed but missing fromusage().Order I'm going in
nv_rtand the examples into the build, unmoved, so there's a signal before anything shifts.--triton --cpugate and the exit code.bc_abend→fe.make install, and a CMake package so people can drop Booth into their own build.Happy to take help on any of it. Thanks @FileDelta for the poke, it turned over a lot more than you'd have guessed.