Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 25 additions & 9 deletions sphinx/migration_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ Guppy is a compiled language which distinguishes it from Python. The user writes

## Loading pytket circuit as Guppy functions

A pytket [Circuit](inv:pytket#circuit_class) instance can be invoked as a Guppy function using the `guppy.load_pytket` method. This feature can be useful for making use of existing pytket circuits directly in Guppy without having to rewrite code from scratch. In the near term, it is also useful to synthesize circuits (e.g. state preparation, permutations) using pytket's higher level "box" constructs. These synthesized circuits can the be invoked as Guppy functions.

[load_pytket_docs]: https://docs.quantinuum.com/guppy/api/decorator.html#guppylang.decorator.guppy.load_pytket

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tried to use relative linking here but seems to not work. I think because the docs for decorator are written manually.


A pytket [Circuit](inv:pytket#circuit_class) instance can be invoked as a Guppy function using the [guppy.load_pytket][load_pytket_docs] method. This feature can be useful for making use of existing pytket circuits directly in Guppy without having to rewrite code from scratch. In the near term, it is also useful to synthesize circuits (e.g. state preparation, permutations) using pytket's higher level "box" constructs. These synthesized circuits can the be invoked as Guppy functions.

### Basic Example

Expand All @@ -43,8 +46,8 @@ qft_func = guppy.load_pytket("qft_func", qft2_circ)

We now have a Guppy function called `qft_func` which we can compile or use as a subroutine in other functions.

Note that by default `guppy.load_pytket` will create Guppy functions which use arrays of qubits as inputs. This means that our `qft_func` above will have take an array of two qubits as input.
If we want the function to take two separate qubit arguments, we can specify `use_arrays=False` in `guppy.load_pytket`. Also note that by default, circuits with separate quantum registers become Guppy functions that take multiple arrays of qubits as input.
Note that by default [guppy.load_pytket][load_pytket_docs] will create Guppy functions which use arrays of qubits as inputs. This means that our `qft_func` above will have take an array of two qubits as input.
If we want the function to take two separate qubit arguments, we can specify `use_arrays=False` in [guppy.load_pytket][load_pytket_docs]. Also note that by default, circuits with separate quantum registers become Guppy functions that take multiple arrays of qubits as input.


### How to deal with operations unsupported by Guppy
Expand Down Expand Up @@ -91,10 +94,23 @@ pytket_circ.add_gate(G_box, [0, 1])
pytket_circ.CCX(0, 1, 2)
pytket_circ.add_gate(OpType.CnY, [0, 1, 2])

guppy_func = guppy.load_pytket("circuit_func", pytket_circ)
# Load pytket circuit as a Guppy function.
circuit_func = guppy.load_pytket("circuit_func", pytket_circ)
```

We now have a Guppy function that takes three qubits as input. As this function has inputs, it cannot be an entrypoint to an executable program. We therefore have to call `circuit_func` inside a Guppy function which takes no arguments and allocates some qubits for it to use.

```{code-cell} ipython3
from guppylang.std.quantum import discard_array

@guppy
def guppy_func() -> None:
qs = array(qubit() for _ in range(3))
circuit_func(qs)
discard_array(qs)
```

We will get an error if we try to invoke the Selene emulator as it cannot execute the opaque op.
We will get an error if we try to invoke the Selene emulator as it cannot execute the opaque op defining the {py:class}`~pytket.circuit.Unitary2qBox` in the call to `circuit_func`.

```{code-cell} ipython3
---
Expand All @@ -106,7 +122,7 @@ sim_result = guppy_func.emulator(n_qubits=3).with_seed(2).run()

The solution to handling operations which are not directly supported is to decompose
these unsupported operations into gates from the supported extensions before loading the circuit. This can
be readily done with the `AutoRebase` pass from pytket.
be readily done with the {py:class}`~pytket.passes.AutoRebase` pass from pytket.

```{code-cell} ipython3
from pytket.passes import AutoRebase, DecomposeBoxes
Expand All @@ -118,18 +134,18 @@ DecomposeBoxes().apply(pytket_circ) # Decompose the Unitary2qBox to primitive ga
rebase_pass.apply(pytket_circ) # Convert all gates in pytket_circ to {H, Rz, CX}

# Load rebased circuit as a Guppy function
guppy_func = guppy.load_pytket("guppy_func", pytket_circ)
new_circuit_func = guppy.load_pytket("guppy_func", pytket_circ)
```

Now our compiled Guppy program should contain no opaque operations and is executable on the emulator.
Now our compiled Guppy program should contain no opaque operations and is executable on the emulator when called inside `guppy_func`.

## Compilation and optimization of quantum programs

The pytket library contains many [compilation passes](https://docs.quantinuum.com/tket/api-docs/passes.html) for transforming quantum programs. Many of these passes are designed to optimize quantum circuits to reduce the number of entangling quantum gates. Using pytket, we can also convert programs to the native gateset of a quantum device and solve for qubit connectivity constraints.

As of August 2025, optimization of compiled Guppy programs is still at an early stage. When using `guppy.emulator()` the quantum program is converted to the [qsystem native instructions](api/generated/guppylang.std.qsystem.rst) with no further optimization. In the near term, it is planned to optimize regions of these programs with the kind of compiler passes that are already available in pytket using an updated version of the TKET compiler.

If you want to optimize your quantum program using pytket, you can create a pytket circuit and optimize it. This optimized program can then be loaded as a Guppy function by using `guppy.load_pytket`.
If you want to optimize your quantum program using pytket, you can create a pytket circuit and optimize it. This optimized program can then be loaded as a Guppy function by using [guppy.load_pytket][load_pytket_docs].

## Execution of quantum programs

Expand Down