Skip to content

Compile artifacts

loom-compile specializes one verified .loom or .loombc module and emits an artifact for a selected backend. It is the offline form of the same parse, link, configure, specialize, lower, and emit operations available through the loomc API.

The shortest useful invocation names the input, backend, target profile, and artifact path. Reports, manifests, and IR traces are optional evidence products, not boilerplate required by every compile.

Compile for a HAL loader

Compile one targetless kernel for the generic GFX11 profile:

loom-compile kernel.loom \
  --backend=amdgpu-hal \
  --target=gfx11-generic \
  --output=kernel.hsaco

The primary output is the executable byte sequence consumed by the selected HAL loader. For AMDGPU that representation is currently an HSACO. The source module can contain checks, reference functions, template providers, and other authoring support; the HAL backend materializes kernel entries and their dependency closures into the executable library.

Backend availability is a property of the installed Loom tool. Target pages own driver setup and supported profile names; the compile workflow remains the same across backends.

Choose generic or exact specialization

A generic profile retains portability within one target family:

loom-compile kernel.loom \
  --backend=amdgpu-hal \
  --target=gfx11-generic \
  --output=kernel-gfx11.hsaco

An exact profile exposes the features and limits of one physical target:

loom-compile kernel.loom \
  --backend=amdgpu-hal \
  --target=gfx1151 \
  --output=kernel-gfx1151.hsaco

--target specializes every materialized kernel entry before the compile pipeline. An authored target remains a compatibility requirement: a generic GFX11 entry can specialize to gfx1151, while an entry constrained to an incompatible family fails. A HAL compile only needs --target when a materialized root does not already carry an authored target.

Reusable libraries generally omit authored targets. Their source can then specialize for the target selected by the application, benchmark, or artifact build rather than fragmenting into target-specific copies.

Select roots from a catalog

When --root is omitted, a HAL backend compiles every kernel entry and its dependency closure. Select one or more entries from a catalog by repeating the flag:

loom-compile catalog.loombc \
  --root=@prefill \
  --root=@decode \
  --backend=amdgpu-hal \
  --target=gfx11-generic \
  --output=qwen-kernels.hsaco

Root selection is reachability, not name filtering after compilation. Unused functions, providers, configurations, checks, and kernels are absent from the materialized compile module.

Use loom-link first when several independently shipped modules must be composed. Use --root directly when one linked catalog already contains the complete declared dependency graph.

Bind compile-time configuration

Bind the config.decl values that describe this artifact:

loom-compile kernel.loombc \
  --root=@decode \
  --backend=amdgpu-hal \
  --target=gfx1151 \
  --config=model.hidden_size=4096 \
  --config=model.head_count=32 \
  --output=decode.hsaco

JSON and JSONC files carry larger configuration objects:

loom-compile kernel.loombc \
  --backend=amdgpu-hal \
  --target=gfx1151 \
  --config-file=model-config.jsonc \
  --output=model-kernels.hsaco

Configuration materializes before root dependency walking and the pass pipeline. Specialization can therefore select providers and remove unreachable paths before later compilation work. Nested JSON keys flatten with . separators; explicit bindings not referenced by the module are ignored.

Compile a VM-targeted module

The VM backend emits a VM bytecode archive from functions authored for an ireevm.target:

loom-compile program.loom \
  --backend=vm \
  --output=program.vmfb

This is an artifact backend, not an implicit reference interpreter for an arbitrary device kernel. The module still states which functions target the VM and which entry points are public.

Target-owned emitters can also expose intermediate deployment formats directly. For example, an installation with the LLVM IR emitter can write textual or bitcode artifacts:

loom-compile kernel.loom --backend=llvmir-text --output=kernel.ll
loom-compile kernel.loom --backend=llvmir-bitcode --output=kernel.bc

Emit a target-native sidecar

A HAL backend may have both a loader-ready representation and a target-native artifact. Request both when an integration needs the primary loader product and tooling needs the native object:

loom-compile kernel.loom \
  --backend=amdgpu-hal \
  --target=gfx11-generic \
  --output=kernel.executable \
  --emit-target-artifact=kernel.hsaco

The two byte sequences may be identical. AMDGPU currently uses HSACO for both; the separate output contract still matters for backends whose loader container and native artifact differ.

Emit an artifact manifest

An artifact manifest describes the loader product without asking a consumer to reverse-engineer it:

loom-compile kernel.loom \
  --backend=amdgpu-hal \
  --target=gfx11-generic \
  --output=kernel.hsaco \
  --artifact-manifest=summary

With a filesystem artifact output, the manifest path defaults to kernel.hsaco.manifest.json. Name it explicitly when packaging has a fixed layout:

loom-compile kernel.loom \
  --backend=amdgpu-hal \
  --target=gfx11-generic \
  --output=kernel.hsaco \
  --artifact-manifest=details \
  --emit-artifact-manifest=kernel.manifest.json

Summary manifests expose the stable loader-facing inventory. Details and analysis modes add progressively richer target metadata. The manifest answers which functions, exports, bindings, launch sizes, constants, and target facts are present; it does not explain why the compiler chose them.

jq '.functions[] | {name, target, workgroup_size}' kernel.manifest.json

Keep compiler evidence separate

The primary artifact is what a runtime loads. The target-native sidecar is what target tooling consumes. The manifest describes the emitted interface. A compile report records compiler and emitted-code evidence. An IR trace records the program at selected pipeline boundaries.

Generate each product only for the consumer that needs it. Routine application builds can stop at the artifact; tuning runs continue with Read compile reports.