RNG Capability¶
Note
Pytket only supports random 32-bit integer generation and this is only executable on select Quantinuum targets.
Floating-point numbers cannot be randomly generated with pytket.
Emulator targets suffixed with
Eare supported. Nexus-hosted emulators and local emulators are not supported.Execution is only possible if OpenQASM is selected as the language option upon execute job submission.
System Model H2 provides an integrated pseudo Random Number Generator (RNG) capability with the pytket circuit builder API (pytket.circuit). This enables generation and consumption of random integers during real-time program execution. The RNG capability is also available on Quantinuum Helios via Guppy. The RNG capability is executed on the control system (ARM Cortex processor).
Usage¶
Pytket’s circuit builder API provides instance methods to perform RNG operations on classical bit registers. The exact register size required to use the available RNG functions is specified the table below.
Function  | 
Classical Register Width  | 
|---|---|
  | 
64  | 
  | 
32  | 
  | 
32  | 
  | 
32  | 
Set RNG Seed¶
tket:pytket.circuit.set_rng_seed()
Seed an RNG from the contents of a classical register.
The classical register must be exactly 64 bits.
circ = Circuit()
creg = circ.add_c_register("c", 64)
circ.add_c_setbits([True, True], [creg[3], creg[11]])
circ.set_rng_seed(creg)
Set RNG Bound¶
tket:pytket.circuit.set_rng_bound()
Set an RNG upper bound from the contents of a classical register. The exact sequence of random numbers can be reproduced by setting the same master seed and stream index.
The classical register must be exactly 32 bits. It encodes the upper bound in little-endian binary (least significant bit first). The bound is inclusive.
circ = Circuit()
creg = circ.add_c_register("c", 32)
circ.add_c_setbits([True, True], [creg[3], creg[11]])
circ.set_rng_bound(creg)
Set RNG Index¶
tket:pytket.circuit.set_rng_index()
Set an RNG stream index from the contents of a classical register.
The classical register must be exactly 32 bits. It encodes the index in little- endian binary (least significant bit first).
circ = Circuit()
creg = circ.add_c_register("c", 32)
circ.add_c_setbits([True, True], [creg[3], creg[11]])
circ.set_rng_index(creg)
Set RNG Numbers¶
tket:pytket.circuit.get_rng_num()
Get RNG output into a classical register.
The classical register must be exactly 32 bits. After the operation it encodes the output number in little-endian binary (least significant bit first).
circ = Circuit()
creg = circ.add_c_register("c", 32)
circ.get_rng_num(creg)
Use Case: Adaptive Circuit Synthesis¶
The code sample generates random bounded 32-bit integers between ([0, 3)). The random integers correspond to the following physical operations with a native tket:pytket.circuit.Circuit.PhasedX(). The function, tket:pytket.circuit.Circuit.add_c_setreg(), is used to set a specified classical register to an integer value.
The PhasedX operation is used to perform the following Pauli operations:
Pauli-X,
Pauli-Y,
Pauli-Z,
from pytket.circuit import Circuit
from pytket.circuit.logic_exp import reg_eq
circuit = Circuit(1)
seed = circuit.add_c_register("seed", 64)
bound = circuit.add_c_register("bound", 32)
circuit.add_c_setreg(1, bound)
circuit.add_c_setreg(3, bound)
index = circuit.add_c_register("index", 32)
op = circuit.add_c_register("op", 32)
# for _ in range(5):
circuit.get_rng_num(op)
circuit.PhasedX(1, 0, 0, condition=reg_eq(op, 0))
circuit.PhasedX(0, 1, 0, condition=reg_eq(op, 1))
circuit.PhasedX(1, 1, 0, condition=reg_eq(op, 2))
circuit.measure_all()
circuit.n_bits
The circuit can be submitted to Quantinuum emulators or hardware via the usual Nexus workflow.
import qnexus as qnx
import uuid
project = qnx.projects.get_or_create("RNG")
qnx.context.set_active_project(project)
resource_suffix = uuid.uuid1()
Quantinuum Backend configuration
config = qnx.QuantinuumConfig(
    device_name="H2-2E",
)
Circuit upload to Nexus database.
circ_ref = qnx.circuits.upload(circuit=circuit, name=f"rng-circuit-{resource_suffix}")
Server-side Circuit Compilation
compile_ref = qnx.start_compile_job(
    programs=[circ_ref],
    name=f"compile-job-{resource_suffix}",
    optimisation_level=0,
    backend_config=config
)
qnx.jobs.wait_for(compile_ref)
ref_compile_circuit = qnx.jobs.results(compile_ref)[0].get_output()
Execute job submission
execute_ref = qnx.start_execute_job(
    programs=[ref_compile_circuit],
    name=f"execute-job-{resource_suffix}",
    n_shots=[100],
    backend_config=config,
    language=qnx.models.language.Language.QASM
)
qnx.jobs.wait_for(execute_ref)
result_ref = qnx.jobs.results(execute_ref)[0]
execute_ref
backend_result = result_ref.download_result()
print(backend_result.get_distribution())
Conversions¶
OpenQASM¶
from pytket.qasm import circuit_to_qasm_str
qasm_str = circuit_to_qasm_str(circuit, header="hqslib1", maxwidth=64)
with open("rng.qasm", "w") as file_io:
    file_io.write(qasm_str)
QIR¶
from pytket.qir import pytket_to_qir, QIRFormat
qir_str = pytket_to_qir(circuit, qir_format=QIRFormat.STRING)
with open("rng.ll", "w") as file_io:
    file_io.write(qir_str)