Pytket worker¶
A Tierkreis worker that interacts with the Quantinuums pytket toolkit.
The pytket worker largely wraps the functionality from tket.
Installation¶
pip install tkr-pytket-worker
will install an executable Python script tkr_pytket_worker into your virtual environment.
Authentication¶
Certain backends, such as the Quantinnuum backend require authentication.
The worker uses the default mechanisms provided by the qnexus Python package.
uv run python -c "from qnexus.client.auth import login; login()"
will put the a token in the appropriate filesystem location for subsequent operations to use.
To use IBMQ services, the credentials are expected to be stored in a file $HOME/.qiskit/qiskit-ibm.json for more see the Qiskit Documentation
Elementary tasks¶
The pytket worker exposes the following elementary tasks to the user:
add_measure_alladds final measurements to a circuit.append_pauli_measurement_impladds measurements according to a Pauli string to a circuit.optimise_phase_gadgetsapplies the phase gadget optimization pass to a circuit.apply_passapplies a user defined optimization pass.compilegeneric compile function with a variety of optionscompile_circuit_quantinuumandcompile_circuits_quantinuumapply a predefined level 3 optimization for Quantinuum devices to a (list of) circuit.compile_tket_circuit_ibmandcompile_tket_circuits_ibmapplies the pytket default pass for IBM devices to a (list of) circuit. Requires IBMQ authentication.compile_tket_circuit_quantinuumandcompile_tket_circuits_quantinuumapplies the pytket default pass for Quantinuum devices to a (list of) circuit. Requires Qautninuum Nexus authentication.to_qasm_strandfrom_gasm_strtransforms a Circuit to/from QASM 2.to_qir_bytesandfrom_qir_bytestransforms a Circuit to/from QIR. Requires optional dependenciesuv sync --groups qir.expectationestimates the expectation value from shot counts.n_qubitsreturns the number of qubits in a const circuit.
Example¶
An example use is in examples/pytket_graph.py in the Tierkreis repo, which runs on a named IBM backend, e.g. "ibm_torino".
For debugging purposes this also showcases how to use the InMemoryExecutor which only works in conjunction with the InMemoryStorage.
class IBMInput(NamedTuple):
circuit: TKR[OpaqueType["pytket._tket.circuit.Circuit"]] # noqa: F821
n_shots: TKR[int]
backend: TKR[str]
def compile_run_single():
g = GraphBuilder(
IBMInput, TKR[OpaqueType["pytket.backends.backendresult.BackendResult"]]
)
compiled_circuit = g.task(
compile_tket_circuit_ibm(
circuit=g.inputs.circuit,
backend_name=g.inputs.backend,
optimization_level=g.const(2),
)
)
res = g.task(submit_single(compiled_circuit, g.inputs.n_shots))
g.outputs(res)
return g
circuit = ...your circuit here...
storage = InMemoryStorage(UUID(int=109))
executor = InMemoryExecutor(
Path(__file__).parent.parent / "tierkreis_workers", storage
)
n_shots = 30
run_graph(
storage,
executor,
g,
{
"circuit": ghz(),
"n_shots": n_shots,
"backend": "<ibm_backend>", # e.g. ibm_torino
},
)
res = read_outputs(g, storage)
print(res)