qat.middleend.decompositions.base module
- class DecompositionBase(end_nodes=None, extend_end_nodes=None)
Bases:
objectDecomposition objects implement the rules for decomposing gates into native gates.
The object should be equipped with a
decompose_op()method that is implemented using single dispatch. This allows us to register a decomposition for each relevant gate / operation type. Note that decompositions should be implemented carefully, and form a directed acyclic graph (DAG) that terminates atNativeGatenodes.Assumming all relevant nodes are implemented, an operation can be decomposed to a series of native gates / operations using the
decompose()method, which will recursively calldecompose_op().As a rule of thumb, try not to use logic on gate angles to define the decomposition. They should be kept general. If there are instances where a choice of angle(s) can be decomposed more effeciently, a transformation pass should be used to substitute the gate. This is done to allow predictable behaviour, and has parameterised circuits in mind.
- Parameters:
end_nodes¶ (
Optional[list[QubitInstruction]]) – Optionally specify the nodes to end the decomposition recursion at. Defaults todecompositions.end_nodes.extend_end_nodes¶ (
Optional[list[QubitInstruction]]) – By default the decomposition will recurse until all gates are aNativeGate. You can optionally add additional (nonNativeGate) gates to terminate at. This argument should only be specified ifend_nodes=None.
- decompose(gate, *args)
Recursively decomposes an instruction into a product of native gates.
- Parameters:
gate¶ (
QubitInstruction) – Gate to decompose.
- decompose_op(gate, *args)
Implements the definition of a decomposition of a qubit operation.
The definition does not have to be in terms of end nodes, but decompositions must form a DAG. For example,
CNOT -> {ECR, X, Z} -> {ZX_pi_4, Z_phase, X_pi_2} U -> {x_pi_2, Z_phase}
- end_nodes = ()