Adding a Pass
A pass is a single transformation step on a TesseraCircuit. Adding a new one is intentionally minimal. Create a file, inherit from TranspilerPass, implement run(), add it to the pipeline, and write the tests. Nothing else in the codebase needs to change.
Step 1: Create the Pass File
Create a new file in tessera/passes/. The filename should match the pass name in snake case:
tessera/passes/my_pass.pyStep 2: Implement the Pass
Inherit from TranspilerPass and implement run(). The contract is simple: receive a TesseraCircuit, return a TesseraCircuit. Always forward circuit.layout to the returned circuit unless your pass has a specific reason to change it. Dropping the layout will cause to_qiskit() to size the output circuit incorrectly.
from tessera.circuit import TesseraCircuit
from tessera.transpiler_pass import TranspilerPass
class MyPass(TranspilerPass):
def __init__(self):
pass # add constructor params here if needed
def run(self, circuit: TesseraCircuit) -> TesseraCircuit:
instructions = []
for ins in circuit.instructions:
# transform or filter instructions here
instructions.append(ins)
return TesseraCircuit(circuit.num_qubits, circuit.num_clbits, instructions, circuit.layout)A few conventions to follow:
- Always preserve
circuit.layoutin the returned circuit unless your pass explicitly reassigns physical qubits - Passes that take configuration (like a threshold, a mode flag, or a coupling map) should accept it in
__init__, notrun() - Keep the pass single-purpose. If you find yourself doing two distinct things, split them into two passes
Step 3: Add It to the Pipeline
Open tessera/transpiler.py and import your pass, then add an instance of it to the passes list in TesseraTranspiler.__init__(). The order matters because passes run sequentially and each receives the output of the previous one.
from tessera.passes.my_pass import MyPass
passes = [
BasisTranslationPass(self.backend),
DenseLayoutPass(self.coupling_map),
BasicSwapRouter(self.coupling_map, self.path_finder),
BasisTranslationPass(self.backend),
RemoveBarriersPass(),
CancelAdjacentPass(self.strict),
MergeRotationsPass(self.strict, self.epsilon),
MyPass() # add here in the appropriate position
]If your pass takes configuration parameters that should be user-controllable, add them to TesseraTranspiler.__init__() and pass them through to the constructor.
Step 4: Write the Tests
Create a corresponding test file in tests/:
tests/test_my_pass.pyAt minimum, cover:
- Happy path: a circuit where the pass makes the expected transformation
- No-op case: a circuit where nothing should change, and verify nothing does
- Edge cases: empty circuit, single instruction, circuit with only measurements
- Any exceptions your pass raises
A typical test constructs a TesseraCircuit directly, calls pass_.run(circuit), and asserts on the output instructions:
from tessera.circuit import TesseraCircuit
from tessera.instruction import TesseraInstruction
from tessera.passes.my_pass import MyPass
def test_my_pass_basic():
instructions = [
TesseraInstruction("x", [0], [], []),
TesseraInstruction("x", [0], [], [])
]
circuit = TesseraCircuit(1, 0, instructions)
result = MyPass().run(circuit)
assert len(result.instructions) == expected_countRun the full suite after adding your tests to make sure nothing else broke:
pytest tests/Optional: Expose Constructor Parameters via the API
If your pass has configuration that users should be able to set via transpile(), add a parameter to both TesseraTranspiler.__init__() in transpiler.py and transpile() in tessera/api/transpile.py. Follow the same pattern as existing parameters like strict and epsilon.