Parameterized Shots¶
The Helios platform provides a function call to get the shot index. The user program can be parameterized by the shot index. The shot index can be returned in Guppy using guppylang.std.qsystem.utils.get_current_shot().
Use Case 1: RNG Seed¶
The seed value can be unique per shot using guppylang.std.qsystem.utils.get_current_shot(). In the code sample provided, the seed is incremented every shot. The RNG object is instantiated every shot and used to generate 32-bit random floats.
from guppylang import guppy
from guppylang.std.angles import angle
from guppylang.std.builtins import result, comptime, array
from guppylang.std.quantum import qubit, measure_array
from guppylang.std.qsystem import zz_phase
from guppylang.std.qsystem.utils import get_current_shot
from guppylang.std.qsystem.random import RNG
INIT_SEED = 0
N = 18
nlayer = 3
@guppy
def layer(
q: array[qubit, comptime(N)],
rng: RNG,
index_shift: bool
) -> None:
a = array(rng.random_float() for _ in range(comptime(N//2)))
result("angle", a)
for k in range(comptime(N//2)):
i = 2 * k + int(index_shift)
j = 2 * k + 1 + int(index_shift)
if i >= comptime(N):
i = i - comptime(N)
if j >= comptime(N):
j = j - comptime(N)
zz_phase(q[i], q[j], angle(a[k]))
@guppy
def main() -> None:
q_array = array(qubit() for _ in range(comptime(18)))
rng = RNG(comptime(INIT_SEED) + get_current_shot())
for _ in range(comptime(nlayer)):
layer(q_array, rng, False)
layer(q_array, rng, True)
r_array = measure_array(q_array)
result("mresult", r_array)
rng.discard()
hugr_binary = main.compile()
import qnexus as qnx
import uuid
unique_suffix = uuid.uuid1()
project = qnx.projects.get_or_create("Helios-Samples")
qnx.context.set_active_project(project)
ref_hugr = qnx.hugr.upload(
hugr_binary,
name=f"rng-usecase0-{unique_suffix}"
)
from quantinuum_schemas import HeliosConfig, HeliosEmulatorConfig, CoinflipSimulator
helios_config = HeliosConfig(
system_name="Helios-1E-lite",
emulator_config=HeliosEmulatorConfig(
simulator=CoinflipSimulator(),
n_qubits=18
),
max_cost=100
)
result_ref = qnx.start_execute_job(
programs=[ref_hugr],
n_shots=[1],
backend_config=helios_config,
name=f"job-rng-usecase0-{unique_suffix}"
)
qnx.jobs.wait_for(result_ref)
job_result = qnx.jobs.results(result_ref)[0].download_result()
print(job_result)
QsysResult(results=[QsysShot(entries=[['angle', [0.13170378981158137, 0.755355317145586, 0.5831400000024587, 0.21037689154036343, 0.9376081398222595, 0.6338424978312105, 0.7061422956176102, 0.06342564942315221, 0.2751847072504461]], ['angle', [0.004724327474832535, 0.18847966892644763, 0.5039901344571263, 0.3183173837605864, 0.14421830116771162, 0.08386536641046405, 0.2119857717771083, 0.6731340079568326, 0.6624895462300628]], ['angle', [0.6486093683633953, 0.6693849647417665, 0.632575634168461, 0.2803243848029524, 0.8352232179604471, 0.03838327317498624, 0.12490360159426928, 0.7011869826819748, 0.9515982016455382]], ['angle', [0.5227349053602666, 0.2847847656812519, 0.27109970338642597, 0.2859301823191345, 0.07285637431778014, 0.8271915337536484, 0.22953439853154123, 0.8056983519345522, 0.12264243187382816]], ['angle', [0.7009257823228836, 0.4759937422350049, 0.027518346207216385, 0.925707106012851, 0.2213007945101708, 0.3689842042513192, 0.6145194519776851, 0.9821490130852908, 0.18022531014867127]], ['angle', [0.4735962741542607, 0.9543152288533748, 0.8398035247810185, 0.4232349132653326, 0.3869804949499666, 0.9539077635854484, 0.251403326401487, 0.9643704514019192, 0.7240403406322002]], ['mresult', [0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1]]])])
Use Case 2: Parameterized Angles¶
Pre-generated angles can be parameterized using the current shot index. The code sample generates a 4 Pauli Exponential primitives across 4-qubits and then measures the qubits. This process is repeated 4 times. The qubits are implictly reused via dynamic qubit allocation.
import numpy as np
from guppylang import guppy
from guppylang.std.angles import angle
from guppylang.std.quantum import cx, rz, measure_array, qubit
from guppylang.std.builtins import comptime, array
from guppylang.std.qsystem.utils import get_current_shot
P = np.random.random_sample((4, 4)) / np.pi
@guppy
def gadget(
gate_angle: angle,
q_array: array[qubit, 4]
) -> None:
for i in range(3):
cx(q_array[i], q_array[i+1])
rz(q_array[3], gate_angle)
for i in range(1, 3):
cx(q_array[4-i-1], q_array[4-i])
@guppy
def main() -> None:
params_set = comptime(P.tolist())
shot_index = get_current_shot()
param = array(p for p in params_set[shot_index])
result("parameters", param)
for _ in range(4):
q_array = array(qubit() for _ in range(4))
for i in range(4):
gadget(angle(param[i]), q_array)
outcome = measure_array(q_array)
result("measurements", outcome)
hugr_binary = main.compile()
ref_hugr = qnx.hugr.upload(
hugr_binary,
name=f"rng-usecase1-{unique_suffix}"
)
from quantinuum_schemas import HeliosConfig, HeliosEmulatorConfig, CoinflipSimulator
helios_config = HeliosConfig(
system_name="Helios-1E-lite",
emulator_config=HeliosEmulatorConfig(
simulator=CoinflipSimulator(),
n_qubits=4
),
max_cost=100
)
result_ref = qnx.start_execute_job(
programs=[ref_hugr],
n_shots=[1],
backend_config=helios_config,
name=f"job-rng-usecase1-{unique_suffix}"
)
qnx.jobs.wait_for(result_ref)
job_result = qnx.jobs.results(result_ref)[0].download_result()
print(job_result)
QsysResult(results=[QsysShot(entries=[['parameters', [0.17475093599078026, 0.07096292756164177, 0.16380001625697804, 0.22018444811175183]], ['measurements', [0, 1, 1, 0]], ['measurements', [0, 1, 0, 0]], ['measurements', [1, 1, 1, 0]], ['measurements', [1, 0, 1, 1]]])])
qnx.jobs.status(result_ref).status
<JobStatusEnum.ERROR: 'ERROR'>