Skip to content
Closed
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
17 changes: 16 additions & 1 deletion qiskit_braket_provider/providers/braket_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from braket.aws import AwsDevice, AwsQuantumTask, AwsQuantumTaskBatch
from braket.aws.queue_information import QueueDepthInfo
from braket.circuits import Circuit
from braket.circuits.noise_model import NoiseModel as BraketNoiseModel
from braket.device_schema import DeviceActionType
from braket.devices import Device, LocalSimulator
from braket.tasks.local_quantum_task import LocalQuantumTask
Expand Down Expand Up @@ -59,7 +60,12 @@ def _get_gateset(self) -> Optional[set[str]]:
class BraketLocalBackend(BraketBackend):
"""BraketLocalBackend."""

def __init__(self, name: str = "default", **fields):
def __init__(
self,
name: str = "default",
noise_model: Optional[BraketNoiseModel] = None,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be a qiskit noise model that we would translate to Braket before L88.

**fields,
):
"""AWSBraketLocalBackend for local execution of circuits.

Example:
Expand All @@ -71,11 +77,15 @@ def __init__(self, name: str = "default", **fields):

Args:
name: name of backend
noise_model (Optional[NoiseModel]): The Braket noise model to apply to the circuit
before execution. Noise model can only be added to the devices that support
noise simulation.
**fields: extra fields
"""
super().__init__(name=name, **fields)
self.backend_name = name
self._local_device = LocalSimulator(backend=self.backend_name)
self._local_device.set_noise_model(noise_model)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should have a self.set_noise_model(noise_model: QiskitNoiseModel) and translate noise_model and apply it to self._local_device.

self._target = local_simulator_to_target(self._local_device)
self.status = self._local_device.status

Expand Down Expand Up @@ -178,6 +188,7 @@ def __init__( # pylint: disable=too-many-arguments
description: str = None,
online_date: datetime.datetime = None,
backend_version: str = None,
noise_model: Optional[BraketNoiseModel] = None,
**fields,
):
"""AWSBraketBackend for execution circuits against AWS Braket devices.
Expand All @@ -196,6 +207,9 @@ def __init__( # pylint: disable=too-many-arguments
description: description of backend
online_date: online date
backend_version: backend version
noise_model (Optional[NoiseModel]): The Braket noise model to apply to the circuit
before execution. Noise model can only be added to the devices that support
noise simulation.
**fields: other arguments
"""
super().__init__(
Expand All @@ -208,6 +222,7 @@ def __init__( # pylint: disable=too-many-arguments
)
user_agent = f"QiskitBraketProvider/{version.__version__}"
device.aws_session.add_braket_user_agent(user_agent)
device.set_noise_model(noise_model)
self._aws_device = device
self._target = aws_device_to_target(device=device)

Expand Down
8 changes: 7 additions & 1 deletion qiskit_braket_provider/providers/braket_provider.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
"""AWS Braket provider."""

from typing import Optional

from braket.aws import AwsDevice
from braket.circuits.noise_model import NoiseModel as BraketNoiseModel
from braket.device_schema.dwave import DwaveDeviceCapabilities
from braket.device_schema.quera import QueraDeviceCapabilities
from braket.device_schema.xanadu import XanaduDeviceCapabilities
Expand Down Expand Up @@ -28,7 +31,9 @@ class AWSBraketProvider(ProviderV1):
BraketBackend[dm1]]
"""

def backends(self, name=None, **kwargs):
def backends(
self, name=None, noise_model: Optional[BraketNoiseModel] = None, **kwargs
):
if kwargs.get("local"):
return [BraketLocalBackend(name="default")]
names = [name] if name else None
Expand Down Expand Up @@ -57,6 +62,7 @@ def backends(self, name=None, **kwargs):
description=f"AWS Device: {device.provider_name} {device.name}.",
online_date=device.properties.service.updatedAt,
backend_version="2",
noise_model=noise_model,
)
)
return backends
10 changes: 10 additions & 0 deletions tests/providers/mocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
RIGETTI_ARN = "arn:aws:braket:::device/qpu/rigetti/Aspen-10"
RIGETTI_ASPEN_ARN = "arn:aws:braket:::device/qpu/rigetti/Aspen-M-3"
SV1_ARN = "arn:aws:braket:::device/quantum-simulator/amazon/sv1"
DM1_ARN = "arn:aws:braket:::device/quantum-simulator/amazon/dm1"
TN1_ARN = "arn:aws:braket:::device/quantum-simulator/amazon/tn1"
RIGETTI_REGION = "us-west-1"
SIMULATOR_REGION = "us-west-1"
Expand Down Expand Up @@ -136,6 +137,15 @@
"deviceCapabilities": MOCK_GATE_MODEL_SIMULATOR_CAPABILITIES.json(),
}

MOCK_GATE_MODEL_SIMULATOR_DM = {
"deviceName": "dm1",
"deviceType": "SIMULATOR",
"providerName": "provider1",
"deviceStatus": "ONLINE",
"deviceArn": DM1_ARN,
"deviceCapabilities": MOCK_GATE_MODEL_SIMULATOR_CAPABILITIES.json(),
}

MOCK_GATE_MODEL_SIMULATOR_TN = {
"deviceName": "tn1",
"deviceType": "SIMULATOR",
Expand Down
18 changes: 18 additions & 0 deletions tests/providers/test_braket_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from qiskit_braket_provider.providers import AWSBraketBackend, BraketLocalBackend
from qiskit_braket_provider.providers.adapter import aws_device_to_target
from tests.providers.mocks import (
MOCK_GATE_MODEL_SIMULATOR_CAPABILITIES,
RIGETTI_MOCK_GATE_MODEL_QPU_CAPABILITIES,
RIGETTI_MOCK_M_3_QPU_CAPABILITIES,
)
Expand Down Expand Up @@ -75,6 +76,16 @@ def test_device_backend(self):
with self.assertRaises(NotImplementedError):
backend.control_channel([0, 1])

def test_aws_backend_noise_model(self):
"""Tests local backend."""
mock_noise_model = Mock()
mock_set_noise_model = Mock()
device = Mock()
device.properties = MOCK_GATE_MODEL_SIMULATOR_CAPABILITIES
device.set_noise_model = mock_set_noise_model
_ = AWSBraketBackend(device, noise_model=mock_noise_model)
self.assertEqual(mock_set_noise_model.call_args[0][0], mock_noise_model)

def test_local_backend(self):
"""Tests local backend."""
backend = BraketLocalBackend(name="default")
Expand All @@ -90,6 +101,13 @@ def test_local_backend(self):
with self.assertRaises(NotImplementedError):
backend.control_channel([0, 1])

@patch("braket.devices.LocalSimulator.set_noise_model")
def test_local_backend_noise_model(self, mock_set_noise_model):
"""Tests local backend."""
mock_noise_model = Mock()
_ = BraketLocalBackend(name="default", noise_model=mock_noise_model)
self.assertEqual(mock_set_noise_model.call_args[0][0], mock_noise_model)

def test_local_backend_output(self):
"""Test local backend output"""
first_backend = BraketLocalBackend(name="braket_dm")
Expand Down
19 changes: 18 additions & 1 deletion tests/providers/test_braket_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
BraketBackend,
)
from tests.providers.mocks import (
MOCK_GATE_MODEL_SIMULATOR_DM,
MOCK_GATE_MODEL_SIMULATOR_SV,
MOCK_GATE_MODEL_SIMULATOR_TN,
MOCK_RIGETTI_GATE_MODEL_M_3_QPU,
Expand All @@ -30,7 +31,11 @@ class TestAWSBraketProvider(TestCase):

def setUp(self):
self.mock_session = Mock()
simulators = [MOCK_GATE_MODEL_SIMULATOR_SV, MOCK_GATE_MODEL_SIMULATOR_TN]
simulators = [
MOCK_GATE_MODEL_SIMULATOR_SV,
MOCK_GATE_MODEL_SIMULATOR_DM,
MOCK_GATE_MODEL_SIMULATOR_TN,
]
self.mock_session.get_device.side_effect = simulators
self.mock_session.region = SIMULATOR_REGION
self.mock_session.boto_session.region_name = SIMULATOR_REGION
Expand Down Expand Up @@ -71,6 +76,18 @@ def test_real_devices(self):
with self.subTest(f"{backend.name}"):
self.assertIsInstance(backend, AWSBraketBackend)

@patch("qiskit_braket_provider.providers.braket_provider.AWSBraketBackend")
@patch("qiskit_braket_provider.providers.braket_backend.AwsDevice.get_devices")
def test_get_backend_noise_model(self, mock_get_devices, mock_aws_braket_backend):
"""Tests qiskit circuit transpilation."""
mock_noise_model = Mock()
mock_get_devices.return_value = [Mock()]
provider = AWSBraketProvider()
_ = provider.get_backend(name="dm1", noise_model=mock_noise_model)
self.assertEqual(
mock_aws_braket_backend.call_args[1]["noise_model"], mock_noise_model
)

@patch("qiskit_braket_provider.providers.braket_backend.AWSBraketBackend")
@patch("qiskit_braket_provider.providers.braket_backend.AwsDevice.get_devices")
def test_qiskit_circuit_transpilation_run(
Expand Down