Skip to content
Open
Show file tree
Hide file tree
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
3 changes: 2 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@
package_dir={"": "src"},
install_requires=[
"amazon-braket-schemas>=1.21.3",
"amazon-braket-default-simulator>=1.26.0",
# "amazon-braket-default-simulator>=1.26.0",
"amazon-braket-default-simulator@git+https://github.com/Altanali/amazon-braket-default-simulator-python.git@optional_net_detuning", # noqa: E501
"oqpy~=0.3.5",
"backoff",
"boltons",
Expand Down
23 changes: 22 additions & 1 deletion src/braket/aws/aws_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
from braket.ahs.analog_hamiltonian_simulation import AnalogHamiltonianSimulation
from braket.annealing.problem import Problem
from braket.aws.aws_emulation import (
ahs_criterion,
ahs_noise_model,
connectivity_validator,
gate_connectivity_validator,
gate_validator,
Expand All @@ -42,7 +44,12 @@
from braket.circuits import Circuit, Gate, QubitSet
from braket.circuits.gate_calibrations import GateCalibrations
from braket.circuits.noise_model import NoiseModel
from braket.device_schema import DeviceCapabilities, ExecutionDay, GateModelQpuParadigmProperties
from braket.device_schema import (
DeviceActionType,
DeviceCapabilities,
ExecutionDay,
GateModelQpuParadigmProperties,
)
from braket.device_schema.dwave import DwaveProviderProperties

# TODO: Remove device_action module once this is added to init in the schemas repo
Expand Down Expand Up @@ -896,6 +903,14 @@ def emulator(self) -> Emulator:
return self._emulator

def _setup_emulator(self) -> Emulator:
if DeviceActionType.OPENQASM in self.properties.action.keys():
return self._setup_gate_device_emulator()
elif DeviceActionType.AHS in self.properties.action.keys():
return self._setup_ahs_device_emulator()
else:
raise ValueError(f"Emulators for device {self._name} are not supported.")

def _setup_gate_device_emulator(self) -> Emulator:
"""
Sets up an Emulator object whose properties mimic that of this AwsDevice, if the device is a
real QPU (not a simulator).
Expand All @@ -915,6 +930,12 @@ def _setup_emulator(self) -> Emulator:
self._emulator.add_pass(gate_connectivity_validator(self.properties, self.topology_graph))
return self._emulator

def _setup_ahs_device_emulator(self) -> Emulator:
self._emulator = Emulator(backend="braket_ahs", name=self._name)
self._emulator.add_pass(ahs_criterion(self.properties))
self._emulator.add_pass(ahs_noise_model(self.properties))
return self._emulator

def validate(
self,
task_specification: ProgramType,
Expand Down
122 changes: 122 additions & 0 deletions src/braket/aws/aws_emulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@
from braket.device_schema import DeviceActionType, DeviceCapabilities
from braket.device_schema.ionq import IonqDeviceCapabilities
from braket.device_schema.iqm import IqmDeviceCapabilities
from braket.device_schema.quera import QueraDeviceCapabilities
from braket.device_schema.rigetti import RigettiDeviceCapabilities
from braket.emulation.emulation_passes.ahs_passes import AhsValidator, AhsNoise, AhsNoiseData
from braket.emulation.emulation_passes.ahs_passes.device_capabilities_constants import (
DeviceCapabilitiesConstants,
)
from braket.emulation.emulation_passes.gate_device_passes import (
ConnectivityValidator,
GateConnectivityValidator,
Expand All @@ -16,6 +21,7 @@
)



def qubit_count_validator(properties: DeviceCapabilities) -> QubitCountValidator:
"""
Create a QubitCountValidator pass which checks that the number of qubits used in a program does
Expand Down Expand Up @@ -212,3 +218,119 @@ def _(properties: RigettiDeviceCapabilities, gate_name: str) -> str:
def _(properties: IonqDeviceCapabilities, gate_name: str) -> str:
translations = {"GPI": "GPi", "GPI2": "GPi2"}
return translations.get(gate_name, gate_name)


def ahs_criterion(properties: DeviceCapabilities) -> AhsValidator:
"""
Creates an AHS program validation pass using the input QPU device capabilities.

Args:
properties (DeviceCapabilities): Device capabilities of a QPU device that supports
Analog Hamiltonian Simulation Programs.

Returns:
AhsValidator: An emulator pass that validates whether or not an AHS program is able to run
on the target device.
"""
device_capabilities_constants = _get_ahs_device_capabilities(properties)
return AhsValidator(device_capabilities_constants)


@singledispatch
def _get_ahs_device_capabilities(properties: DeviceCapabilities) -> DeviceCapabilitiesConstants:
raise NotImplementedError(
"AHS Device Capabilities Constants cannot be created"
f"using capabilities type ({type(properties)})"
)


@_get_ahs_device_capabilities.register(QueraDeviceCapabilities)
def _(properties: QueraDeviceCapabilities) -> DeviceCapabilitiesConstants:
properties = properties.dict()
capabilities = dict()
lattice = properties["paradigm"]["lattice"]
capabilities["MAX_SITES"] = lattice["geometry"]["numberSitesMax"]
capabilities["MIN_DISTANCE"] = lattice["geometry"]["spacingRadialMin"]
capabilities["MIN_ROW_DISTANCE"] = lattice["geometry"]["spacingVerticalMin"]
capabilities["SITE_PRECISION"] = lattice["geometry"]["positionResolution"]
capabilities["BOUNDING_BOX_SIZE_X"] = lattice["area"]["width"]
capabilities["BOUNDING_BOX_SIZE_Y"] = lattice["area"]["height"]
capabilities["MAX_FILLED_SITES"] = properties["paradigm"]["qubitCount"]

rydberg = properties["paradigm"]["rydberg"]
rydberg_global = rydberg["rydbergGlobal"]
capabilities["MIN_TIME"] = rydberg_global["timeMin"]
capabilities["MAX_TIME"] = rydberg_global["timeMax"]
capabilities["GLOBAL_TIME_PRECISION"] = rydberg_global["timeResolution"]
capabilities["GLOBAL_MIN_TIME_SEPARATION"] = rydberg_global["timeDeltaMin"]

(
capabilities["GLOBAL_AMPLITUDE_VALUE_MIN"],
capabilities["GLOBAL_AMPLITUDE_VALUE_MAX"],
) = rydberg_global["rabiFrequencyRange"]
capabilities["GLOBAL_AMPLITUDE_VALUE_PRECISION"] = rydberg_global["rabiFrequencyResolution"]
capabilities["GLOBAL_AMPLITUDE_SLOPE_MAX"] = rydberg_global["rabiFrequencySlewRateMax"]

(
capabilities["GLOBAL_PHASE_VALUE_MIN"],
capabilities["GLOBAL_PHASE_VALUE_MAX"],
) = rydberg_global["phaseRange"]
capabilities["GLOBAL_PHASE_VALUE_PRECISION"] = rydberg_global["phaseResolution"]

(
capabilities["GLOBAL_DETUNING_VALUE_MIN"],
capabilities["GLOBAL_DETUNING_VALUE_MAX"],
) = rydberg_global["detuningRange"]
capabilities["GLOBAL_DETUNING_VALUE_PRECISION"] = rydberg_global["detuningResolution"]
capabilities["GLOBAL_DETUNING_SLOPE_MAX"] = rydberg_global["detuningSlewRateMax"]

rydberg_local = rydberg.get("rydbergLocal")
if rydberg_local:
capabilities["LOCAL_RYDBERG_CAPABILITIES"] = True
capabilities["LOCAL_MIN_DISTANCE_BETWEEN_SHIFTED_SITES"] = rydberg_local["spacingRadialMin"]
capabilities["LOCAL_TIME_PRECISION"] = rydberg_local["timeResolution"]
capabilities["LOCAL_MIN_TIME_SEPARATION"] = rydberg_local["timeDeltaMin"]
(
capabilities["LOCAL_MAGNITUDE_SEQUENCE_VALUE_MIN"],
capabilities["LOCAL_MAGNITUDE_SEQUENCE_VALUE_MAX"],
) = rydberg_local["detuningRange"]
capabilities["LOCAL_MAGNITUDE_SLOPE_MAX"] = rydberg_local["detuningSlewRateMax"]
capabilities["LOCAL_MAX_NONZERO_PATTERN_VALUES"] = rydberg_local[
"numberLocalDetuningSitesMax"
]
(
capabilities["MAGNITUDE_PATTERN_VALUE_MIN"],
capabilities["MAGNITUDE_PATTERN_VALUE_MAX"],
) = rydberg_local["siteCoefficientRange"]

return DeviceCapabilitiesConstants.parse_obj(capabilities)



def ahs_noise_model(properties: DeviceCapabilities) -> AhsNoise:
return _ahs_noise_model(properties)

@singledispatch
def _ahs_noise_model(properties: DeviceCapabilities) -> AhsNoise:
raise NotImplementedError("An AHS noise model cannot be created from device capabilities of "
f"type {type(properties)}.")

@_ahs_noise_model.register(QueraDeviceCapabilities)
def _(properties: QueraDeviceCapabilities):

capabilities = properties.paradigm
performance = capabilities.performance
noise_data = AhsNoiseData(
site_position_error= float(performance.lattice.sitePositionError),
filling_error = float(performance.lattice.vacancyErrorTypical),
vacancy_error = float(performance.lattice.vacancyErrorTypical),
ground_prep_error = float(performance.rydberg.rydbergGlobal.groundPrepError),
rabi_amplitude_ramp_correction = performance.rydberg.rydbergGlobal.rabiAmplitudeRampCorrection,
rabi_frequency_error_rel = float(performance.rydberg.rydbergGlobal.rabiFrequencyGlobalErrorRel),
detuning_error = float(performance.rydberg.rydbergGlobal.detuningError),
detuning_inhomogeneity = float(performance.rydberg.rydbergGlobal.detuningInhomogeneity),
atom_detection_error_false_positive = float(performance.lattice.atomDetectionErrorFalsePositiveTypical),
atom_detection_error_false_negative = float(performance.lattice.atomDetectionErrorFalseNegativeTypical),
rabi_amplitude_max = float(capabilities.rydberg.rydbergGlobal.rabiFrequencyRange[-1])
)
return AhsNoise(noise_data)
5 changes: 5 additions & 0 deletions src/braket/emulation/emulation_passes/ahs_passes/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from braket.emulation.emulation_passes.ahs_passes.ahs_validator import AhsValidator # noqa: F40
from braket.emulation.emulation_passes.ahs_passes.ahs_noisy_pass import( #noqa: F40
AhsNoise,
AhsNoiseData
)
Loading