Skip to content

Commit

Permalink
update documentation, move over get_compiled_circuit/s
Browse files Browse the repository at this point in the history
  • Loading branch information
sjdilkes committed Nov 21, 2024
1 parent 044d715 commit 59ed800
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 3 deletions.
3 changes: 2 additions & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,8 @@ compiled_circ = backend.get_compiled_circuit(circ)
```

The passes applied by different levels of optimisation are specified in the table below. Note that optimisation level 0, 1 and 2 do not remove barriers from
a circuit, while optimisation level 3 will.
a circuit, while optimisation level 3 will. At optimisation level 3 the default timeout is 5 minutes - consider increasing this for larger circuits if
the circuit 2-qubit gate count is not reduced after compilation.

:::{list-table} **Default compilation pass for the QuantinuumBackend**
:widths: 25 25 25
Expand Down
102 changes: 100 additions & 2 deletions pytket/extensions/quantinuum/backends/quantinuum.py
Original file line number Diff line number Diff line change
Expand Up @@ -661,11 +661,16 @@ def default_compilation_pass(
self, optimisation_level: int = 2, timeout: int = 300
) -> BasePass:
"""
:param optimisation_level: Allows values of 0,1 or 2, with higher values
:param optimisation_level: Allows values of 0, 1, 2 or 3, with higher values
prompting more computationally heavy optimising compilation that
can lead to reduced gate count in circuits.
:param timeout: Only valid for optimisation level 3, gives a maximimum time
for running a single thread of the pass `GreedyPauliSimp`. Increase for
optimising larger circuits.
:return: Compilation pass for compiling circuits to Quantinuum devices
"""
print("Timeout: ", timeout)
assert optimisation_level in range(4)
passlist = [
DecomposeBoxes(),
Expand Down Expand Up @@ -734,7 +739,32 @@ def default_compilation_pass(
passlist.extend(
[
RemoveBarriers(),
AutoRebase({OpType.CX, OpType.Rz, OpType.H}),
AutoRebase(
{
OpType.Z,
OpType.X,
OpType.Y,
OpType.S,
OpType.Sdg,
OpType.V,
OpType.Vdg,
OpType.H,
OpType.CX,
OpType.CY,
OpType.CZ,
OpType.SWAP,
OpType.Rz,
OpType.Rx,
OpType.Ry,
OpType.T,
OpType.Tdg,
OpType.ZZMax,
OpType.ZZPhase,
OpType.XXPhase,
OpType.YYPhase,
OpType.PhasedX,
}
),
GreedyPauliSimp(
allow_zzphase=True,
only_reduce=True,
Expand Down Expand Up @@ -771,6 +801,74 @@ def default_compilation_pass(
passlist.append(FlattenRelabelRegistersPass("q"))
return SequencePass(passlist)

def get_compiled_circuit(
self, circuit: Circuit, optimisation_level: int = 2, timeout: int = 300
) -> Circuit:
"""
Return a single circuit compiled with :py:meth:`default_compilation_pass`.
:param optimisation_level: Allows values of 0, 1, 2 or 3, with higher values
prompting more computationally heavy optimising compilation that
can lead to reduced gate count in circuits.
:type optimisation_level: int, optional
:param timeout: Only valid for optimisation level 3, gives a maximimum time
for running a single thread of the pass `GreedyPauliSimp`. Increase for
optimising larger circuits.
:type timeout: int, optional
:return: An optimised quantum circuit
:rtype: Circuit
"""
return_circuit = circuit.copy()
if optimisation_level == 3 and circuit.n_gates_of_type(OpType.Barrier) > 0:
warnings.warn(
f"Barrier operations in this circuit will be removed when using optimisation level 3."
)
self.default_compilation_pass(optimisation_level, timeout).apply(return_circuit)
return return_circuit

def get_compiled_circuits(
self,
circuits: Sequence[Circuit],
optimisation_level: int = 2,
timeout: int = 300,
) -> list[Circuit]:
"""Compile a sequence of circuits with :py:meth:`default_compilation_pass`
and return the list of compiled circuits (does not act in place).
As well as applying a degree of optimisation (controlled by the
`optimisation_level` parameter), this method tries to ensure that the circuits
can be run on the backend (i.e. successfully passed to
:py:meth:`process_circuits`), for example by rebasing to the supported gate set,
or routing to match the connectivity of the device. However, this is not always
possible, for example if the circuit contains classical operations that are not
supported by the backend. You may use :py:meth:`valid_circuit` to check whether
the circuit meets the backend's requirements after compilation. This validity
check is included in :py:meth:`process_circuits` by default, before any circuits
are submitted to the backend.
If the validity check fails, you can obtain more information about the failure
by iterating through the predicates in the `required_predicates` property of the
backend, and running the :py:meth:`verify` method on each in turn with your
circuit.
:param circuits: The circuits to compile.
:type circuit: Sequence[Circuit]
:param optimisation_level: The level of optimisation to perform during
compilation. See :py:meth:`default_compilation_pass` for a description of
the different levels (0, 1, 2 or 3). Defaults to 2.
:type optimisation_level: int, optional
:param timeout: Only valid for optimisation level 3, gives a maximimum time
for running a single thread of the pass `GreedyPauliSimp`. Increase for
optimising larger circuits.
:type timeout: int, optional
:return: Compiled circuits.
:rtype: List[Circuit]
"""
return [
self.get_compiled_circuit(c, optimisation_level, timeout) for c in circuits
]

@property
def _result_id_type(self) -> _ResultIdTuple:
return tuple((str, str, int, str))
Expand Down

0 comments on commit 59ed800

Please sign in to comment.