Expression Graph
hologram-graph is the directed acyclic graph the compiler consumes. A graph
is a flat list of Nodes; each node’s op slot is a GraphOp, and its inputs
reference earlier nodes, constants, or graph-input ports.
Graph— the append-only node list, shape registry, and constant storeNode—{ op: GraphOp, inputs: SmallVec<[InputSource; 4]>, output_dtype: DTypeId, output_shape: ShapeId }GraphOp—Input,Output,Op(OpKind), orConstant(ConstantId)OpKind— the closed op catalog (re-exported fromhologram_ops):Relu,Sigmoid,MatMul,Gemm,Conv2d,LayerNorm,Softmax,Attention,Gather(runtime-indexed embedding lookup),Cast(numeric dtype conversion), and many moreInputSource—Node(NodeId),Constant(ConstantId), orGraphInput(u32)NodeId/ConstantId— opaque handlesConstantStore— inline constant tensors
From hologram_graph::registry:
DTypeId(u8)— dtype tag (e.g.DTypeId(8)= f32)ShapeDescriptor— rank + dims; constructors likeShapeDescriptor::rank2(m, n)ShapeId— handle into the internedShapeRegistry
There is no GraphBuilder; graphs are built directly from Node values.
Construction
Section titled “Construction”use hologram_graph::{Graph, Node, GraphOp, OpKind, InputSource};use hologram_graph::registry::{DTypeId, ShapeDescriptor};use smallvec::SmallVec;
let mut g = Graph::new();let f32 = DTypeId(8);let s = g.shape_registry_mut().intern(ShapeDescriptor::rank2(2, 3));
let x = g.add_node(Node { op: GraphOp::Input, inputs: SmallVec::new(), output_dtype: f32, output_shape: s,});g.add_input(x);
let y = g.add_node(Node { op: GraphOp::Op(OpKind::Relu), inputs: SmallVec::from_iter([InputSource::Node(x)]), output_dtype: f32, output_shape: s,});
let out = g.add_node(Node { op: GraphOp::Output, inputs: SmallVec::from_iter([InputSource::Node(y)]), output_dtype: f32, output_shape: s,});g.add_output(out);Named ports & extensions
Section titled “Named ports & extensions”g.add_input(node) / g.add_output(node) register a port with an empty name. To
give a port a semantic identity (so a multi-input model can be addressed by name
rather than position), use g.add_named_input(node, "input_ids") /
g.add_named_output(node, "logits") — the name and the node’s shape travel into
the archive’s PortDescriptor and surface at runtime through
InferenceSession::input_port_by_name / output_port_by_name.
Producer-defined metadata (tokenizer, generation config, class labels, calibration
tables, provenance) is attached with g.add_extension(key, bytes); it flows
through compile() into an open, repeatable Extension archive section and is
read back at runtime via InferenceSession::extension(key) / extension_keys().
Shapes & constants
Section titled “Shapes & constants”Shapes are interned through g.shape_registry_mut().intern(...), which returns
a ShapeId referenced by Node::output_shape. Inline constants live in the
constant store (g.constants_mut()) and are referenced via
InputSource::Constant(ConstantId).
Compilation
Section titled “Compilation”A built Graph is handed directly to hologram_compiler::Compiler (or the
free compile function), which desugars composites, elides invariants,
schedules, and emits a .holo archive. See the
Compiler Pipeline reference.