Inspecting the pipeline
Before anything leaves your machine, after you build, and when the platform compiles. Three instruments cover the loop.
HomValue for pt_shape, pt_scale, and levelsBefore deploy: inspect the state locally
HomValue for pt_shape, pt_scale, and levels (active rows and active columns on the q-list). Look for a shape that doesn't line up, a scale that outgrows, or a level budget running dry. The printed graph below is the more visual view of the same three fields, on every node at once. See Ciphertext state → Visualizing it yourself for how to read them.After build: print the compiled graph
--print_graph to lattica-build.# build the MNIST example and print the compiled graph
lattica-build --pipeline-module lattica_build.examples.example_mnist_fc --out /tmp/quickstart_mnist.zip --print_graph--print_graph, you will see output like this. The tree depends on the pipeline; below is the MNIST example from Build the pipeline.Lattica Pipeline ════════════════ ● x shape=(@100, 1, 1, 784) q=[61] [45] primary client_pre ────────── └─ [0] Composite ├─ x shape=(@100, 1, 1, 784) q=[61] [45] │ └─ [0.0] Reshape dims=[100, 1, 1, 784] ├─ x shape=(@100, 1, 1, 784) q=[61] [45] └─ → v0 shape=(100, 1, 1, 784) scale=1048576 q=[61] [45] │ └─ → v0 shape=(100, 1, 1, 784) scale=1048576 q=[61] [45] hom ─── └─ [0] Composite ├─ x shape=(@100, 1, 1, 784) q=[61] [45] │ ├─ [0.0] Composite │ ├─ x shape=(@100, 1, 1, 784) q=[61] [45] │ │ │ └─ [0.0.0] MatMul │ dims=[50, 784] │ mul_axis=-1 │ with_modswitch=False │ ├─ x shape=(@100, 1, 1, 784) q=[61] [45] │ └─ → v0 shape=(@100, 1, 50) scale=1099511627776 q=[61] [45] │ │ │ └─ → v0 shape=(@100, 1, 50) scale=1099511627776 q=[61] [45] ├─ [0.1] Composite │ ├─ x shape=(@100, 1, 50) scale=1099511627776 q=[61] [45] │ │ │ └─ [0.1.0] Mul │ keep_axis=False │ with_modswitch=False │ ├─ x shape=(@100, 1, 50) scale=1099511627776 q=[61] [45] │ ├─ x shape=(@100, 1, 50) scale=1099511627776 q=[61] [45] │ └─ → v0 shape=(@100, 1, 50) scale=1208925819614629174706176 q=[61] [45] │ │ │ └─ → v0 shape=(@100, 1, 50) scale=1208925819614629174706176 q=[61] [45] └─ [0.2] Composite ├─ x shape=(@100, 1, 50) scale=1208925819614629174706176 q=[61] [45] │ └─ [0.2.0] MatMul dims=[10, 50] mul_axis=-1 with_modswitch=False ├─ x shape=(@100, 1, 50) scale=1208925819614629174706176 q=[61] [45] └─ → v0 shape=(@100, 10) scale=1267650600228229401496703205376 q=[61] [45] │ └─ → v0 shape=(@100, 10) scale=1267650600228229401496703205376 q=[61] [45] │ └─ → v2 shape=(@100, 10) scale=1267650600228229401496703205376 q=[61] [45] client_post ─────────── └─ [0] Composite ├─ x shape=(@100, 1, 1, 784) q=[61] [45] │ └─ [0.0] Softmax dim=-1 ├─ x shape=(@100, 1, 1, 784) q=[61] [45] └─ → v0 shape=(100, 10) scale=1267650600228229401496703205376 q=[61] [45] │ └─ → v0 shape=(100, 10) scale=1267650600228229401496703205376 q=[61] [45]
MatMuls and the Mul (the square) run encrypted. Softmax runs after decrypt. Scale grows after each multiply.client_pre, hom, client_post: where the op runs.
[0], [0.1.0]: composition and execution order.
The primitive that ran: Reshape, MatMul, Mul, Softmax.
v0, v2: how data flows from one node to the next.
Traced shape. @ marks the slots / n axis.
pt_scale at that point in the graph.
Remaining modulus-chain state: the q-list still active on that value.
From the compiler: accuracy, latency, memory
The loop
HomValue. Print the graph when you want the whole tree. Then deploy. If the compiler rejects the pipeline, the error sends you back to Build. The debugger shows the HomValue that broke; the graph shows where shape or scale changed. Fix it, print again, deploy, and read the report.The debugger and the printed graph stay on your machine. Use them after any change to the encrypted body (between preprocess and postprocess). Deploying triggers a compile, so don't deploy on every small change. Treat the report as the final word on accuracy, latency, and memory.
Next
Run Queries
The pipeline checks out. After Key generation, start the worker and send encrypted queries.