Compiler Pipeline
hologram-compiler turns a hologram_graph::Graph into a .holo archive: a
self-contained, content-addressed artifact the executor can load and run. The
compiler is no_std + alloc by default, so the whole pipeline runs in wasm and
on embedded targets; the std feature only adds tracing diagnostics.
Pipeline Steps
Section titled “Pipeline Steps”The per-graph pipeline (Compiler::compile) runs in order:
- Desugar composite ops into their primitive-op pipelines (e.g.
Clip→Min∘Max) - Algebraic elision — drop computation UOR’s algebra proves unnecessary (identity elements, involutions, dead nodes)
- Schedule — compute topological levels
- Per-node compile: emit a Term tree, build and validate a
CompileUnit, run completeness - Cache certificates by content fingerprint over
(op_kind, witt_level, backend) - Lower each node to a backend
KernelCall - Weight-layout monomorphism — pre-pack constant matmul weights into the panel layout (zero runtime copy)
- Emit the
.holoarchive (kernel calls, schedule, exec plan, weights, constants, ports, certificates)
Compiler— main entry point; owns the graph, targetBackendKind, andWittLevelCompilationOutput—{ archive: Vec<u8>, stats: CompilationStats }CompilationStats— node/level counts plus cache hit/miss and validated-unit talliesBackendKind—Cpu,Avx2,Avx512,Neon,Metal,WgpuCompileError— the pipeline’s error type
WittLevel comes from prism::vocabulary.
Compile a programmatically built graph:
use hologram_compiler::{Compiler, BackendKind};use prism::vocabulary::WittLevel;
let output = Compiler::new(graph, BackendKind::Cpu, WittLevel::W32).compile()?;let archive: Vec<u8> = output.archive;Or use the free compile function:
use hologram_compiler::{compile, BackendKind};use prism::vocabulary::WittLevel;
let output = compile(graph, BackendKind::Cpu, WittLevel::W32)?;Compiling from source
Section titled “Compiling from source”All source frontends lower through the same boundary:
source text -> SourceDocument -> selected SourceProgram -> Graph -> CompilerSourceDocument lets frontends extract one or more graph regions from a larger
host-language file before the compiler selects a single SourceProgram for
lowering. This keeps source-language spans and AST details out of the graph IR,
archive, backend, and executor.
hologram_compiler::source::parse remains the compatibility entry point for
native Hologram source. It accepts both the original line-oriented grammar
(# comments and blank lines ignored) and the native frontend path:
input x :2x3op relu x as=youtput yuse hologram_compiler::{compile_from_source, BackendKind};use prism::vocabulary::WittLevel;
let src = "input x\nop relu x as=y\noutput y\n";let output = compile_from_source(src, WittLevel::W32, BackendKind::Cpu)?;source::parse returns Result<Graph, CompileError> if you want the graph
without compiling.
Use the language-aware API when the source file may contain more than one graph region or when it is written in a host-language frontend:
use hologram_compiler::source::{self, SourceLanguage, SourceParseOptions};
let options = SourceParseOptions::new().graph("encoder");let program = source::parse_ir_with_options( py_source, SourceLanguage::Python, &options,)?;let graph = source::lower_ir(&program)?;If graph selection is not needed, compile source directly with the language convenience API:
use hologram_compiler::source::SourceLanguage;use hologram_compiler::{compile_from_source_language, BackendKind};use prism::vocabulary::WittLevel;
let output = compile_from_source_language( py_source, SourceLanguage::Python, WittLevel::W32, BackendKind::Cpu,)?;The CLI detects source language by extension for .txt, .py, .ts, .tsx,
and .rs. Pass --source-language <lang> only for unusual extensions or an
explicit override. Pass --graph <name> when a file contains multiple graph
regions.
Python and TypeScript SDK packages also expose native Hologram .txt
compilation through the FFI. Use hg.compile_source_file("graph.txt") in
Python, or compileSource(...) from @hologram/sdk with a native/WASM binding
in TypeScript. The Node adapter adds compileSourceFile("graph.txt") for
filesystem-backed source files.
Python frontend
Section titled “Python frontend”The Python frontend is behind the frontend-python feature on
hologram-compiler and hologram-cli. It parses Python source as an AST and
extracts restricted Hologram builder functions; it does not import, evaluate, or
execute user Python code. Unrelated Python code is ignored. If a file contains
one inferred graph, it is selected automatically; if it contains multiple graph
functions, pass --graph.
def ordinary_app_code(): return 42
def encoder(h): x = h.input("x", dtype="f32", shape=[2, 3]) w = h.const("w", shape=[3, 2], values=[1, 2, 3, 4, 5, 6]) y = h.ops.matmul(x, w, shape=[2, 2]) h.output("y", y)cargo run -p hologram-cli --features frontend-python -- compile \ --source graph.py \ --graph encoder \ --output model.holoThe accepted Python subset is currently h.input, h.const / h.constant,
h.ops.<op>, and h.output with literal shape, dtype, constant values,
and the same op attributes accepted by native Hologram source. Unsupported
statements inside an inferred graph function fail loudly; ordinary Python
functions with no Hologram builder calls are ignored.
TypeScript frontend
Section titled “TypeScript frontend”The TypeScript frontend is behind the frontend-typescript feature on
hologram-compiler and hologram-cli. It parses TypeScript source as an AST
and extracts restricted Hologram builder functions; it does not import,
evaluate, or execute user TypeScript code. Unrelated TypeScript code is
ignored. If a file contains one inferred graph, it is selected automatically;
if it contains multiple graph functions, pass --graph.
function ordinaryAppCode() { return 42;}
export function encoder(h: HologramBuilder) { const x = h.input("x", { dtype: "f32", shape: [2, 3] }); const w = h.const("w", { shape: [3, 2], values: [1, 2, 3, 4, 5, 6] }); const y = h.ops.matmul(x, w, { shape: [2, 2] }); h.output("y", y);}cargo run -p hologram-cli --features frontend-typescript -- compile \ --source graph.ts \ --graph encoder \ --output model.holoThe accepted TypeScript subset is currently h.input, h.const /
h.constant, h.ops.<op>, and h.output with object-literal shape, dtype,
constant values, and the same op attributes accepted by native Hologram
source. Unsupported statements inside an inferred graph function fail loudly;
ordinary TypeScript functions with no Hologram builder calls are ignored.
Rust frontend
Section titled “Rust frontend”The Rust frontend is behind the frontend-rust feature on hologram-compiler
and hologram-cli. It parses Rust source with syn and extracts restricted
Hologram builder functions; it does not compile, link, or execute user Rust
code. Unrelated Rust code is ignored. If a file contains one inferred graph, it
is selected automatically; if it contains multiple graph functions, pass
--graph.
fn ordinary_app_code() -> i32 { 42}
pub fn encoder(h: &mut HologramBuilder) { let x = h.input("x", dtype("f32"), shape([2, 3])); let w = h.constant("w", shape([3, 2]), values([1, 2, 3, 4, 5, 6])); let y = h.ops().matmul(x, w, shape([2, 2])); h.output("y", y);}cargo run -p hologram-cli --features frontend-rust -- compile \ --source graph.rs \ --graph encoder \ --output model.holoThe accepted Rust subset is currently h.input, h.constant / h.const_,
h.ops().<op>, and h.output with helper-call shape, dtype, constant
values, and the same op attributes accepted by native Hologram source.
Unsupported statements inside an inferred graph function fail loudly; ordinary
Rust functions with no Hologram builder calls are ignored.