qubosolver.drive_shaping
qubosolver.drive_shaping
Section titled “
qubosolver.drive_shaping
”Drive shaping algorithms for generating quantum drive schedules.
Provides several algorithms for constructing amplitude and detuning waveforms used to solve QUBO problems on neutral-atom hardware.
Modules:
-
local_energy_scale–Local-energy-scale heuristic drive schedule generation for QUBO solving.
-
proportional_diagonal–Proportional-diagonal drive schedule generation for QUBO solving.
qubosolver.drive_shaping.local_energy_scale
Section titled “
qubosolver.drive_shaping.local_energy_scale
”Local-energy-scale heuristic drive schedule generation for QUBO solving.
Functions:
-
build_drive–Generate a local-energy-scale heuristic drive for QUBO solving.
build_drive
Section titled “
build_drive
”build_drive(instance: Instance (qubosolver.Instance)" href="../qubosolver/#qubosolver.Instance">Instance, register: qoolqit.Register, *, device: qoolqit.Device, dmm: bool = True, kappa: float = 0.1) -> qoolqit.DriveGenerate a local-energy-scale heuristic drive for QUBO solving.
For each qubit, the local physical energy scale is
where is the final detuning effectively applied to qubit and is the physical interaction generated by the embedded register.
The peak Rabi frequency is defined as
When DMM is available, the final local detunings are encoded as
with
Without DMM, all atoms receive the same final global detuning
The resulting amplitude and detuning waveforms are clamped or rescaled when necessary so they remain compilable on the target device.
Parameters:
-
instance(Instance) –The QUBO instance whose diagonal encodes target detunings.
-
register(qoolqit (external).Register (external)) –The physical register the drive will run on.
-
device(qoolqit (external).Device (external)) –Target quantum device providing the hardware limits.
-
dmm(bool (external), default:True) –Whether to use the Detuning Map Modulator for local control.
-
kappa(float (external), default:0.1) –Ratio between the peak Rabi frequency and the average local physical energy scale.
Returns:
-
qoolqit (external).Drive (external)–A drive ready for compilation and execution.
Source code in qubosolver/drive_shaping/local_energy_scale.py
def build_drive( instance: Instance, register: qoolqit.Register, *, device: qoolqit.Device, dmm: bool = True, kappa: float = 0.1,) -> qoolqit.Drive: r"""Generate a local-energy-scale heuristic drive for QUBO solving.
For each qubit, the local physical energy scale is
Ei=∣δi(T)∣+∑j≠i∣Vij∣,E_i = |\delta_i(T)| + \sum_{j \neq i} |V_{ij}|,Ei=∣δi(T)∣+j=i∑∣Vij∣,
where δi(T)\delta_i(T)δi(T) is the final detuning effectively applied to qubit iii and VijV_{ij}Vij is the physical interaction generated by the embedded register.
The peak Rabi frequency is defined as
ωmax=κ⋅meani(Ei).\omega_{\max} = \kappa \cdot \text{mean}_i(E_i).ωmax=κ⋅meani(Ei).
When DMM is available, the final local detunings are encoded as
δi(T)=δg(T)+δdmm(T)⋅wi,\delta_i(T) = \delta_g(T) + \delta_{\text{dmm}}(T) \cdot w_i,δi(T)=δg(T)+δdmm(T)⋅wi,
with
\delta_g(T) = d_{\max}, \quad \delta_{\text{dmm}}(T) = -(d_{\max} - d_{\min}), \quad w_i = \frac{d_{\max} - d_i}{d_{\max} - d_{\min}}.
Without DMM, all atoms receive the same final global detuning
δi(T)=δg(T)=meani(di).\delta_i(T) = \delta_g(T) = \text{mean}_i(d_i).δi(T)=δg(T)=meani(di).
The resulting amplitude and detuning waveforms are clamped or rescaled when necessary so they remain compilable on the target device.
Args: instance: The QUBO instance whose diagonal encodes target detunings. register: The physical register the drive will run on. device: Target quantum device providing the hardware limits. dmm: Whether to use the Detuning Map Modulator for local control. kappa: Ratio between the peak Rabi frequency and the average local physical energy scale.
Returns: A drive ready for compilation and execution. """ # Hardware bounds specs = device.specs max_seq_duration: float = specs["max_duration"] or 1000.0 use_dmm = dmm if use_dmm and not support_dmm(device): logging.warning( "dmm=True was requested but device %r does not support a DMM channel; " "falling back to a global detuning drive.", device, ) use_dmm = False
if specs.get("max_amplitude") is not None and specs.get("max_abs_detuning") is not None: device_max_amplitude = specs["max_amplitude"] device_max_abs_detuning = specs["max_abs_detuning"] assert device_max_amplitude is not None # nosec B101 assert device_max_abs_detuning is not None # nosec B101
det_amp_ratio = device_max_amplitude / device_max_abs_detuning
if kappa < det_amp_ratio: logger.warning( f"local_energy_scale_kappa is too small ({kappa}), you're likely to get a " f"qoolqit CompilationError. Set it above {det_amp_ratio}." )
# Target local final detunings. d = (-0.5 * torch.diag(instance.matrix)).detach().cpu() delta_g_T, delta_dmm_T, weights, use_dmm = _detunings(d, use_dmm)
# Final detuning effectively applied to each qubit: # # delta_i(T) = delta_g(T) + delta_dmm(T) * w_i. # # with delta_dmm(T) = 0 when dmm is disabled final_local_detunings = delta_g_T + delta_dmm_T * weights
# Physical interactions generated by the embedded register: # # V_ij = 1 / r_ij**6. # # For each qubit i, compute: # # sum_{j != i} |V_ij|. interaction_scale = matrix.as_tensor(register.interaction_matrix()).abs().sum(dim=0)
# Local physical energy scale: # # E_i = |delta_i(T)| + sum_{j != i} |V_ij|. local_energy_scale = final_local_detunings.abs() + interaction_scale
# Average local physical energy scale: # # E_mean = (1 / n) * sum_i E_i. mean_local_energy_scale = local_energy_scale.mean().item()
# Local-energy-scale mixing rule: # # omega_max = kappa * E_mean. omega_max = kappa * mean_local_energy_scale
# Clamp the amplitude to what can be compiled for this device and register. max_amplitude = max_virtual_amplitude(device, register)
if omega_max > max_amplitude: logger.info( f"The local-energy-scale drive amplitude ({omega_max}) exceeds the maximum " f"amplitude compilable on the device for this register " f"({max_amplitude}); clamping to it." ) omega_max = max_amplitude
# Ensure that the target detunings remain compilable for the selected amplitude. max_detuning = detuning_amplitude_ratio(device) * omega_max * (1.0 - 1e-3) max_abs_d = d.abs().max().item()
if max_abs_d > max_detuning: logger.info( f"The local-energy-scale detuning ({max_abs_d}) exceeds the maximum detuning " f"compilable on the device for this amplitude ({max_detuning}); " f"scaling the detuning down." ) d = d * (max_detuning / max_abs_d) # Recompute the DMM encoding after rescaling the target local detunings. delta_g_T, delta_dmm_T, weights, use_dmm = _detunings(d, use_dmm)
# Keep the initial detuning rule identical to the standard heuristic drive. delta_0 = -d.abs().max().item()
# Amplitude waveform: 0 -> omega_max -> omega_max -> 0. eps = 1e-9 amp_wave = qoolqit.InterpolatedWaveform( max_seq_duration, [eps, omega_max, omega_max, eps], )
# Global detuning waveform: initial negative value -> final target. det_wave = qoolqit.InterpolatedWaveform( max_seq_duration, [delta_0, delta_0, delta_g_T, delta_g_T], )
# Optional DMM weighted detunings. wdetunings = None
if use_dmm: energy_scale = device._target_amp / omega_max wdetunings = constant_weighted_dmm( weights.tolist(), max_seq_duration, final_detuning=delta_dmm_T, device=device, energy_scale=energy_scale, )
return qoolqit.Drive( amplitude=amp_wave, detuning=det_wave, dmm=wdetunings, )
qubosolver.drive_shaping.proportional_diagonal
Section titled “
qubosolver.drive_shaping.proportional_diagonal
”Proportional-diagonal drive schedule generation for QUBO solving.
Functions:
-
build_drive–Generate a proportional-diagonal drive schedule for QUBO solving.
build_drive
Section titled “
build_drive
”build_drive(instance: Instance (qubosolver.Instance)" href="../qubosolver/#qubosolver.Instance">Instance, register: qoolqit.Register, *, device: qoolqit.Device, dmm: bool = True, kappa: float = 1.0) -> qoolqit.DriveGenerate a proportional-diagonal drive schedule for QUBO solving.
Constructs amplitude and detuning waveforms from the QUBO diagonal
coefficients, clamped so they stay within what the compiler can realize
on device for register. When DMM is available, per-atom detuning
weights are computed so that the final local detuning encodes the QUBO
diagonal.
Parameters:
-
instance(Instance) –The QUBO instance whose diagonal encodes target detunings.
-
register(qoolqit (external).Register (external)) –The physical register the drive will run on.
-
device(qoolqit (external).Device (external)) –Target quantum device (provides hardware limits).
-
dmm(bool (external), default:True) –Whether to use the Detuning Map Modulator for local control.
-
kappa(float (external), default:1.0) –Ratio between peak Rabi frequency and peak detuning.
Returns:
-
qoolqit (external).Drive (external)–A drive ready for compilation and execution.
Source code in qubosolver/drive_shaping/proportional_diagonal.py
def build_drive( instance: Instance, register: qoolqit.Register, *, device: qoolqit.Device, dmm: bool = True, kappa: float = 1.0,) -> qoolqit.Drive: """Generate a proportional-diagonal drive schedule for QUBO solving.
Constructs amplitude and detuning waveforms from the QUBO diagonal coefficients, clamped so they stay within what the compiler can realize on `device` for `register`. When DMM is available, per-atom detuning weights are computed so that the final local detuning encodes the QUBO diagonal.
Args: instance: The QUBO instance whose diagonal encodes target detunings. register: The physical register the drive will run on. device: Target quantum device (provides hardware limits). dmm: Whether to use the Detuning Map Modulator for local control. kappa: Ratio between peak Rabi frequency and peak detuning.
Returns: A drive ready for compilation and execution. """ # Hardware bounds specs = device.specs max_seq_duration: float = specs["max_duration"] or 1000.0 use_dmm = dmm if use_dmm and not support_dmm(device): logging.warning( "dmm=True was requested but device %r does not support a DMM channel; " "falling back to a global detuning drive.", device, ) use_dmm = False
if specs.get("max_amplitude") is not None and specs.get("max_abs_detuning") is not None: max_amplitude = specs["max_amplitude"] max_abs_detuning = specs["max_abs_detuning"] assert max_amplitude is not None and max_abs_detuning is not None # nosec B101 det_amp_ratio = max_amplitude / max_abs_detuning if kappa < det_amp_ratio: logger.warning( f"proportional_diagonal_kappa is too small ({kappa}), you're likely to get a " f"qoolqit CompilationError. Set it above {det_amp_ratio}." )
n = instance.size
# Target local final detunings d = (-0.5 * torch.diag(instance.matrix)).cpu().numpy() d_min = float(np.min(d)) d_max = float(np.max(d))
omega_max = kappa * float(np.max(np.abs(d)))
max_amplitude = max_virtual_amplitude(device, register) if omega_max > max_amplitude: logger.info( f"The proportional-diagonal drive amplitude ({omega_max}) exceeds the maximum " f"amplitude compilable on the device for this register " f"({max_amplitude}); clamping to it." ) omega_max = max_amplitude
max_detuning = detuning_amplitude_ratio(device) * omega_max * (1.0 - 1e-3) max_abs_d = float(np.max(np.abs(d))) if max_abs_d > max_detuning: logger.info( f"The proportional-diagonal detuning ({max_abs_d}) exceeds the maximum detuning " f"compilable on the device for this amplitude ({max_detuning}); " f"scaling the detuning down." ) d = d * (max_detuning / max_abs_d) d_min = float(np.min(d)) d_max = float(np.max(d))
if use_dmm: # Final global detuning is the top value, DMM pulls down locally delta_g_T = d_max
# DMM convention required by WeightedDetuning: # waveform must be <= 0 spread = max(0.0, d_max - d_min) # if spread > 1e-15 and delta_dmm_max > 0.0: if spread > 1e-15: delta_dmm_T = -spread # must be <= 0 denom = d_max - d_min weights = ((d_max - d) / denom).clip(0.0, 1.0).tolist() else: use_dmm = False delta_dmm_T = 0.0 weights = [0.0] * n else: # No DMM: use a single global final detuning delta_g_T = np.mean(d) delta_dmm_T = 0.0 weights = [0.0] * n
# How to get max detuning ? delta_0 = -np.max(np.abs(d))
# Amplitude waveform: 0 -> plateau -> 0 eps = 1e-9 amp_wave = qoolqit.InterpolatedWaveform( max_seq_duration, [eps, omega_max, omega_max, eps], )
# Global detuning waveform: initial negative -> final target det_wave = qoolqit.InterpolatedWaveform( max_seq_duration, [delta_0, delta_0, delta_g_T, delta_g_T], )
# DMM weighted detunings wdetunings = None if use_dmm: energy_scale = device._target_amp / omega_max wdetunings = constant_weighted_dmm( weights, max_seq_duration, final_detuning=delta_dmm_T, device=device, energy_scale=energy_scale, )
return qoolqit.Drive( amplitude=amp_wave, detuning=det_wave, dmm=wdetunings, )