qat.plugins.LazySynthesis

class qat.plugins.LazySynthesis(depth: int = 2, reorder: bool = True, merge: bool = True, steiner_method: int = 0, **kwargs)

A plugin wrapping the lazy synthesis based nnization algorithm.

The lazy synthesis algorithms iterate through the input circuit while maintaining a classical data structure describing a particular class of unitary operator (Clifford operators). Upon encountering a gate that’s not part of this class, the algorithms lazily synthesizes a portion of the accumulated operator, just enough to be able to commute the incoming gate with in the remaining operator.

At the end of the compilation, the Plugin updates the Job’s observable using the remaining operator instead of synthesizing it fully, thus saving up even more gates.

The plugin also offers a standalone circuit compilation method .compile_circuit (see below), same thing for jobs.

import networkx as nx
from qat.opt import MaxCut

graph = nx.generators.erdos_renyi_graph(10, 0.1, seed=12)
maxcut = MaxCut(graph)
job = maxcut.to_job("qaoa", 4)
circuit = job.circuit


from qat.devices import RIGETTI_ASPEN as device
from qat.synthopline import LazySynthesis


compiled_circuit, clifford_tableau = LazySynthesis(depth=3).compile_circuit(
    circuit, device.as_graph()
)

print("Initial cnot count:",
      sum(1 if name == "CNOT" else 0
          for name, params, qbits in circuit.iterate_simple()))
print("Final cnot count:",
      sum(1 if name == "CNOT" else 0
          for name, params, qbits in compiled_circuit.iterate_simple()))
print("Final Clifford operator:\n", clifford_tableau)

print("Using Clifford operator lazy synthesis with reordering:")
compiled_circuit, clifford_tableau = LazySynthesis(depth=3, reorder=True).compile_circuit(
    circuit, device.as_graph()
)

print("Initial cnot count:",
      sum(1 if name == "CNOT" else 0
          for name, params, qbits in circuit.iterate_simple()))
print("Final cnot count:",
      sum(1 if name == "CNOT" else 0
          for name, params, qbits in compiled_circuit.iterate_simple()))
print("Final Clifford operator:\n", clifford_tableau)
Initial cnot count: 56
Final cnot count: 330
Final Clifford operator:
 +-xz-xz-xz-xz-xz-xz-xz-xz-xz-xz-xz-xz-xz-xz-xz-xz-
| -- +- -- ++ -- ++ ++ +- ++ ++ ++ ++ ++ -- -- +-
| ZZ __ __ _Z _Z __ XY XZ ZX _Z __ __ __ _Z __ __
| __ Z_ _Z __ ZX __ ZZ __ __ ZZ __ __ __ Z_ __ __
| X_ ZX __ _X __ _Y YZ ZX _Y YY __ __ __ __ __ __
| YZ _X YY _Y _Z _X ZX ZY _X YZ __ __ __ YZ __ __
| _Y _Y ZX _Z _Y _X YX XZ _X ZX __ __ __ ZY __ __
| ZZ _Y _X _Y _Y _Y __ X_ _Y ZX __ __ __ _Y __ __
| _Z _Z _X _Z _Y _Z ZZ Z_ _Z Z_ __ __ __ ZY __ __
| _Z __ __ _Z __ _Z YY YZ ZZ __ __ __ __ __ __ __
| __ __ __ __ __ __ __ __ __ __ __ __ __ __ ZY _X
| __ __ __ __ __ __ __ __ __ __ __ __ __ __ ZZ ZX
| __ __ __ __ __ __ __ __ __ __ XZ __ __ __ __ __
| __ __ __ __ __ __ __ __ __ __ __ XZ __ __ __ __
| __ __ __ __ __ __ __ __ __ __ __ __ XZ __ __ __
| ZZ __ __ ZY _Z __ __ __ __ ZZ __ __ __ _Z __ __
| YZ __ __ _Y _Y Z_ XZ _Y _X XY __ __ __ _Z __ __
| YZ Z_ _Z _Y _Y ZX Y_ _Y _X YX __ __ __ _Z __ __
Using Clifford operator lazy synthesis with reordering:
Initial cnot count: 56
Final cnot count: 330
Final Clifford operator:
 +-xz-xz-xz-xz-xz-xz-xz-xz-xz-xz-xz-xz-xz-xz-xz-xz-
| -- +- -- ++ -- ++ ++ +- ++ ++ ++ ++ ++ -- -- +-
| ZZ __ __ _Z _Z __ XY XZ ZX _Z __ __ __ _Z __ __
| __ Z_ _Z __ ZX __ ZZ __ __ ZZ __ __ __ Z_ __ __
| X_ ZX __ _X __ _Y YZ ZX _Y YY __ __ __ __ __ __
| YZ _X YY _Y _Z _X ZX ZY _X YZ __ __ __ YZ __ __
| _Y _Y ZX _Z _Y _X YX XZ _X ZX __ __ __ ZY __ __
| ZZ _Y _X _Y _Y _Y __ X_ _Y ZX __ __ __ _Y __ __
| _Z _Z _X _Z _Y _Z ZZ Z_ _Z Z_ __ __ __ ZY __ __
| _Z __ __ _Z __ _Z YY YZ ZZ __ __ __ __ __ __ __
| __ __ __ __ __ __ __ __ __ __ __ __ __ __ ZY _X
| __ __ __ __ __ __ __ __ __ __ __ __ __ __ ZZ ZX
| __ __ __ __ __ __ __ __ __ __ XZ __ __ __ __ __
| __ __ __ __ __ __ __ __ __ __ __ XZ __ __ __ __
| __ __ __ __ __ __ __ __ __ __ __ __ XZ __ __ __
| ZZ __ __ ZY _Z __ __ __ __ ZZ __ __ __ _Z __ __
| YZ __ __ _Y _Y Z_ XZ _Y _X XY __ __ __ _Z __ __
| YZ Z_ _Z _Y _Y ZX Y_ _Y _X YX __ __ __ _Z __ __

Warning

The output circuit might not be strictly equivalent to the input circuit.

In the case of standard in-stack usage, the final observable will be permuted according to the final operator, thus producing a functionally equivalent Job.

Note

This Plugin inherits from the CliffordNormalizer interface.

Parameters
  • depth (optional, int) – the depth parameter, default to 2.

  • reorder (optional, bool) – if the strategy is “clifford”, try to optimize the ordering of gates in the input circuit in order to further optimize the circuit. This method comes with a \(O(m^2)\) time overhead (where :math`m` is the number of non-Clifford rotations in the input circuit). This also triggers another optimization that consists in merging some rotations, resulting in possible improvements in the final circuit. Defaults to True.

  • merge (optional, bool) – if the strategy is “clifford”, try to merge rotations when possible. This might reduce the output circuit size significantly in some cases. Default to True.

  • steiner_method (optional, int) – the heuristic to use to compute Steiner trees. 0 for the standard approximation algorithm and 1 for the sketch based approximation algorithm. Use 1 only for large graphs. 1 produces worst trees but faster for large instances.

compile(batch, specs)

The default compile method (that implements the Plugin API)