diff --git a/example.py b/example.py index 03144da7..75cff832 100644 --- a/example.py +++ b/example.py @@ -24,7 +24,11 @@ shots=0, ) dev_qpu = qml.device( - "braket.rigetti", s3_destination_folder=s3, poll_timeout_seconds=1800, shots=10000, wires=2 + "braket.rigetti", + s3_destination_folder=s3, + poll_timeout_seconds=1800, + shots=10000, + wires=2, ) diff --git a/pyproject.toml b/pyproject.toml index aa4949aa..d74c909c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,2 +1,9 @@ -[tool.black] +[tool.ruff] +target-version = "py39" line-length = 100 +lint.isort = { known-first-party = [ + "braket", +] } +lint.extend-select = ["I"] +lint.preview = true + diff --git a/setup.cfg b/setup.cfg index 07405f8b..39d2b595 100644 --- a/setup.cfg +++ b/setup.cfg @@ -8,36 +8,3 @@ addopts = --verbose -n auto --durations=0 --durations-min=1 testpaths = test/unit_tests -[isort] -line_length = 100 -multi_line_output = 3 -include_trailing_comma = true -profile = black - -[flake8] -ignore = - # not pep8, black adds whitespace before ':' - E203, - # not pep8, https://www.python.org/dev/peps/pep-0008/#pet-peeves - E231, - # not pep8, black adds line break before binary operator - W503, - # Google Python style is not RST until after processed by Napoleon - # See https://github.com/peterjc/flake8-rst-docstrings/issues/17 - RST201,RST203,RST301, -max_line_length = 100 -max-complexity = 10 -exclude = - __pycache__ - .tox - .git - bin - build - venv - -rst-roles = - # Python programming language: - py:func,py:mod,mod,class,attr - -rst-directives = - autosummary,currentmodule diff --git a/setup.py b/setup.py index b6db9d45..d9831e15 100644 --- a/setup.py +++ b/setup.py @@ -53,12 +53,8 @@ }, extras_require={ "test": [ - "black", "docutils>=0.19", - "flake8", - "flake8-rst-docstrings", "flaky", - "isort", "pre-commit", "pylint>=3.1.0", "pytest", @@ -67,6 +63,7 @@ "pytest-mock", "pytest-rerunfailures", "pytest-xdist", + "ruff", "sphinx", "sphinx-automodapi", "sphinx-rtd-theme", diff --git a/src/braket/pennylane_plugin/_version.py b/src/braket/pennylane_plugin/_version.py index d879458b..4ded48fc 100644 --- a/src/braket/pennylane_plugin/_version.py +++ b/src/braket/pennylane_plugin/_version.py @@ -12,7 +12,7 @@ # language governing permissions and limitations under the License. """Version information. - Version number (major.minor.patch[-label]) +Version number (major.minor.patch[-label]) """ __version__ = "1.30.1.dev0" diff --git a/src/braket/pennylane_plugin/ahs_device.py b/src/braket/pennylane_plugin/ahs_device.py index 51bf239d..c2fc1678 100644 --- a/src/braket/pennylane_plugin/ahs_device.py +++ b/src/braket/pennylane_plugin/ahs_device.py @@ -32,16 +32,13 @@ Code details ~~~~~~~~~~~~ """ + from collections.abc import Iterable from enum import Enum, auto from typing import Optional, Union import numpy as np import pennylane as qml -from braket.ahs.analog_hamiltonian_simulation import AnalogHamiltonianSimulation -from braket.aws import AwsDevice, AwsQuantumTask, AwsSession -from braket.devices import Device, LocalSimulator -from braket.tasks.local_quantum_task import LocalQuantumTask from pennylane import QubitDevice from pennylane._version import __version__ from pennylane.measurements import MeasurementProcess, SampleMeasurement @@ -49,6 +46,11 @@ from pennylane.pulse import ParametrizedEvolution from pennylane.pulse.hardware_hamiltonian import HardwareHamiltonian, HardwarePulse +from braket.ahs.analog_hamiltonian_simulation import AnalogHamiltonianSimulation +from braket.aws import AwsDevice, AwsQuantumTask, AwsSession +from braket.devices import Device, LocalSimulator +from braket.tasks.local_quantum_task import LocalQuantumTask + from .ahs_translation import ( _create_register, _create_valid_local_detunings, diff --git a/src/braket/pennylane_plugin/ahs_translation.py b/src/braket/pennylane_plugin/ahs_translation.py index 49855bed..2d937612 100644 --- a/src/braket/pennylane_plugin/ahs_translation.py +++ b/src/braket/pennylane_plugin/ahs_translation.py @@ -16,6 +16,10 @@ from typing import Union import numpy as np +from numpy.typing import ArrayLike +from pennylane.pulse import ParametrizedEvolution +from pennylane.pulse.hardware_hamiltonian import HardwarePulse + from braket.ahs.atom_arrangement import AtomArrangement from braket.ahs.driving_field import DrivingField from braket.ahs.field import Field @@ -23,9 +27,6 @@ from braket.ahs.shifting_field import ShiftingField from braket.tasks.analog_hamiltonian_simulation_quantum_task_result import ShotResult from braket.timings.time_series import TimeSeries -from numpy.typing import ArrayLike -from pennylane.pulse import ParametrizedEvolution -from pennylane.pulse.hardware_hamiltonian import HardwarePulse ANGULAR_AND_M_SCALING_FACTOR = 2 * np.pi * 1e6 diff --git a/src/braket/pennylane_plugin/braket_device.py b/src/braket/pennylane_plugin/braket_device.py index fb65de05..13967e1e 100644 --- a/src/braket/pennylane_plugin/braket_device.py +++ b/src/braket/pennylane_plugin/braket_device.py @@ -44,14 +44,6 @@ import numpy as onp import pennylane as qml -from braket.aws import AwsDevice, AwsDeviceType, AwsQuantumTask, AwsQuantumTaskBatch, AwsSession -from braket.circuits import Circuit, Instruction -from braket.circuits.noise_model import NoiseModel -from braket.device_schema import DeviceActionType -from braket.devices import Device, LocalSimulator -from braket.simulator import BraketSimulator -from braket.tasks import GateModelQuantumTaskResult, QuantumTask -from braket.tasks.local_quantum_task_batch import LocalQuantumTaskBatch from pennylane import QuantumFunctionError, QubitDevice from pennylane import numpy as np from pennylane.gradients import param_shift @@ -70,6 +62,17 @@ from pennylane.ops import Hamiltonian, Sum from pennylane.tape import QuantumTape +from braket.aws import ( + AwsDevice, + AwsDeviceType, + AwsQuantumTask, + AwsQuantumTaskBatch, + AwsSession, +) +from braket.circuits import Circuit, Instruction +from braket.circuits.noise_model import NoiseModel +from braket.device_schema import DeviceActionType +from braket.devices import Device, LocalSimulator from braket.pennylane_plugin.translation import ( get_adjoint_gradient_result_type, supported_observables, @@ -78,6 +81,9 @@ translate_result, translate_result_type, ) +from braket.simulator import BraketSimulator +from braket.tasks import GateModelQuantumTaskResult, QuantumTask +from braket.tasks.local_quantum_task_batch import LocalQuantumTaskBatch from ._version import __version__ @@ -253,7 +259,9 @@ def _pl_to_braket_circuit( elif not isinstance(circuit.measurements[0], MeasurementTransform): for measurement in circuit.measurements: translated = translate_result_type( - measurement.map_wires(self.wire_map), None, self._braket_result_types + measurement.map_wires(self.wire_map), + None, + self._braket_result_types, ) if isinstance(translated, tuple): for result_type in translated: @@ -294,7 +302,9 @@ def _apply_gradient_result_type(self, circuit, braket_circuit): return braket_circuit def _update_tracker_for_batch( - self, task_batch: Union[AwsQuantumTaskBatch, LocalQuantumTaskBatch], batch_shots: int + self, + task_batch: Union[AwsQuantumTaskBatch, LocalQuantumTaskBatch], + batch_shots: int, ): for task in task_batch.tasks: tracking_data = self._tracking_data(task) @@ -305,7 +315,9 @@ def _update_tracker_for_batch( self.tracker.record() def statistics( - self, braket_result: GateModelQuantumTaskResult, measurements: Sequence[MeasurementProcess] + self, + braket_result: GateModelQuantumTaskResult, + measurements: Sequence[MeasurementProcess], ) -> list[float]: """Processes measurement results from a Braket task result and returns statistics. diff --git a/src/braket/pennylane_plugin/ops.py b/src/braket/pennylane_plugin/ops.py index 3ea3b7a8..1b2f1179 100644 --- a/src/braket/pennylane_plugin/ops.py +++ b/src/braket/pennylane_plugin/ops.py @@ -533,10 +533,30 @@ def compute_matrix(phi_0, phi_1, theta): return np.array( [ - [np.cos(theta / 2), 0, 0, -1j * np.exp(-1j * (phi_0 + phi_1)) * np.sin(theta / 2)], - [0, np.cos(theta / 2), -1j * np.exp(-1j * (phi_0 - phi_1)) * np.sin(theta / 2), 0], - [0, -1j * np.exp(1j * (phi_0 - phi_1)) * np.sin(theta / 2), np.cos(theta / 2), 0], - [-1j * np.exp(1j * (phi_0 + phi_1)) * np.sin(theta / 2), 0, 0, np.cos(theta / 2)], + [ + np.cos(theta / 2), + 0, + 0, + -1j * np.exp(-1j * (phi_0 + phi_1)) * np.sin(theta / 2), + ], + [ + 0, + np.cos(theta / 2), + -1j * np.exp(-1j * (phi_0 - phi_1)) * np.sin(theta / 2), + 0, + ], + [ + 0, + -1j * np.exp(1j * (phi_0 - phi_1)) * np.sin(theta / 2), + np.cos(theta / 2), + 0, + ], + [ + -1j * np.exp(1j * (phi_0 + phi_1)) * np.sin(theta / 2), + 0, + 0, + np.cos(theta / 2), + ], ] ) diff --git a/src/braket/pennylane_plugin/translation.py b/src/braket/pennylane_plugin/translation.py index 589cecf5..aab1a20f 100644 --- a/src/braket/pennylane_plugin/translation.py +++ b/src/braket/pennylane_plugin/translation.py @@ -17,6 +17,11 @@ import numpy as onp import pennylane as qml +from pennylane import numpy as np +from pennylane.measurements import MeasurementProcess, ObservableReturnTypes +from pennylane.operation import Observable, Operation +from pennylane.pulse import ParametrizedEvolution + from braket.aws import AwsDevice from braket.circuits import FreeParameter, Gate, ResultType, gates, noises, observables from braket.circuits.result_types import ( @@ -30,13 +35,6 @@ ) from braket.device_schema import DeviceActionType from braket.devices import Device -from braket.pulse import ArbitraryWaveform, ConstantWaveform, PulseSequence -from braket.tasks import GateModelQuantumTaskResult -from pennylane import numpy as np -from pennylane.measurements import MeasurementProcess, ObservableReturnTypes -from pennylane.operation import Observable, Operation -from pennylane.pulse import ParametrizedEvolution - from braket.pennylane_plugin.ops import ( AAMS, MS, @@ -48,6 +46,8 @@ GPi2, PRx, ) +from braket.pulse import ArbitraryWaveform, ConstantWaveform, PulseSequence +from braket.tasks import GateModelQuantumTaskResult _BRAKET_TO_PENNYLANE_OPERATIONS = { "i": "Identity", diff --git a/test/integ_tests/conftest.py b/test/integ_tests/conftest.py index c9ad58b1..ebbd3981 100755 --- a/test/integ_tests/conftest.py +++ b/test/integ_tests/conftest.py @@ -59,7 +59,10 @@ shortname_and_backends = [(d.short_name, backend) for (d, backend) in devices] # List of local devices -local_devices = [(BraketLocalQubitDevice, "braket_sv"), (BraketLocalQubitDevice, "braket_dm")] +local_devices = [ + (BraketLocalQubitDevice, "braket_sv"), + (BraketLocalQubitDevice, "braket_dm"), +] # ========================================================== # AWS resources @@ -78,7 +81,8 @@ error_code = e.response["Error"]["Code"] if error_code == "404": s3_bucket.create( - ACL="private", CreateBucketConfiguration={"LocationConstraint": session.region_name} + ACL="private", + CreateBucketConfiguration={"LocationConstraint": session.region_name}, ) diff --git a/test/integ_tests/test_adjoint_gradient.py b/test/integ_tests/test_adjoint_gradient.py index db97a654..ed3f08a5 100644 --- a/test/integ_tests/test_adjoint_gradient.py +++ b/test/integ_tests/test_adjoint_gradient.py @@ -96,7 +96,12 @@ def circuit(x): qml.RZ(rand_param, wires=i) if random.randint(0, 3) == 0: # cnot i with some random other qubit - qml.CNOT(wires=[i, random.choice([j for j in range(num_qubits) if i != j])]) + qml.CNOT( + wires=[ + i, + random.choice([j for j in range(num_qubits) if i != j]), + ] + ) # use every parameter at least once for i in range(num_params): diff --git a/test/integ_tests/test_batch.py b/test/integ_tests/test_batch.py index 6ecd5b01..240bc4f8 100644 --- a/test/integ_tests/test_batch.py +++ b/test/integ_tests/test_batch.py @@ -84,7 +84,8 @@ def func(weights): @pytest.mark.parametrize("shots", [None]) def test_batch_execution_of_gradient_torch(device, shots, mocker): """Test that the output of a parallelized execution of batch circuits to evaluate the - gradient is correct in comparison to default.qubit when using the torch interface.""" + gradient is correct in comparison to default.qubit when using the torch interface. + """ try: import torch except ImportError: diff --git a/test/integ_tests/test_expval.py b/test/integ_tests/test_expval.py index 412f1988..736b5c3b 100755 --- a/test/integ_tests/test_expval.py +++ b/test/integ_tests/test_expval.py @@ -104,7 +104,10 @@ def circuit(): return [qml.expval(qml.Hadamard(i)) for i in range(2)] expected = np.array( - [np.sin(theta) * np.sin(phi) + np.cos(theta), np.cos(theta) * np.cos(phi) + np.sin(phi)] + [ + np.sin(theta) * np.sin(phi) + np.cos(theta), + np.cos(theta) * np.cos(phi) + np.sin(phi), + ] ) / np.sqrt(2) assert np.allclose(circuit(), expected, **tol) diff --git a/test/integ_tests/test_tracking.py b/test/integ_tests/test_tracking.py index 62e77e43..f306b3ab 100644 --- a/test/integ_tests/test_tracking.py +++ b/test/integ_tests/test_tracking.py @@ -17,7 +17,10 @@ import pytest from pennylane import numpy as np -from braket.pennylane_plugin.braket_device import MIN_SIMULATOR_BILLED_MS, BraketAwsQubitDevice +from braket.pennylane_plugin.braket_device import ( + MIN_SIMULATOR_BILLED_MS, + BraketAwsQubitDevice, +) @pytest.mark.parametrize("shots", [100]) diff --git a/test/unit_tests/device_property_jsons.py b/test/unit_tests/device_property_jsons.py index 124b1e99..0d668b85 100644 --- a/test/unit_tests/device_property_jsons.py +++ b/test/unit_tests/device_property_jsons.py @@ -24,7 +24,12 @@ "version": ["1"], "supportedOperations": ["rx", "ry", "h", "cy", "cnot", "unitary"], "supportedResultTypes": [ - {"name": "StateVector", "observables": None, "minShots": 0, "maxShots": 0}, + { + "name": "StateVector", + "observables": None, + "minShots": 0, + "maxShots": 0, + }, { "name": "AdjointGradient", "observables": ["x", "y", "z", "h", "i", "hermitian"], @@ -97,7 +102,12 @@ "version": ["1"], "supportedOperations": ["rx", "ry", "h", "cy", "cnot", "unitary"], "supportedResultTypes": [ - {"name": "StateVector", "observables": None, "minShots": 0, "maxShots": 0}, + { + "name": "StateVector", + "observables": None, + "minShots": 0, + "maxShots": 0, + }, { "name": "AdjointGradient", "observables": ["x", "y", "z", "h", "i"], @@ -115,14 +125,20 @@ "measurements": [[0, 0], [0, 0], [0, 0], [1, 1]], "measuredQubits": [0, 1], "taskMetadata": { - "braketSchemaHeader": {"name": "braket.task_result.task_metadata", "version": "1"}, + "braketSchemaHeader": { + "name": "braket.task_result.task_metadata", + "version": "1", + }, "id": "task_arn", "shots": 100, "deviceId": "default", }, "additionalMetadata": { "action": { - "braketSchemaHeader": {"name": "braket.ir.openqasm.program", "version": "1"}, + "braketSchemaHeader": { + "name": "braket.ir.openqasm.program", + "version": "1", + }, "source": "qubit[2] q; cnot q[0], q[1]; measure q;", }, }, @@ -140,10 +156,17 @@ "resultTypes": [ {"type": {"targets": [0], "type": "probability"}, "value": [0.5, 0.5]}, { - "type": {"observable": ["x"], "targets": [1], "type": "expectation"}, + "type": { + "observable": ["x"], + "targets": [1], + "type": "expectation", + }, "value": 0.0, }, - {"type": {"observable": ["y"], "targets": [2], "type": "variance"}, "value": 0.1}, + { + "type": {"observable": ["y"], "targets": [2], "type": "variance"}, + "value": 0.1, + }, { "type": {"observable": ["z"], "targets": [3], "type": "sample"}, "value": [1, -1, 1, 1], @@ -151,14 +174,20 @@ ], "measuredQubits": [0, 1, 2, 3], "taskMetadata": { - "braketSchemaHeader": {"name": "braket.task_result.task_metadata", "version": "1"}, + "braketSchemaHeader": { + "name": "braket.task_result.task_metadata", + "version": "1", + }, "id": "task_arn", "shots": 0, "deviceId": "default", }, "additionalMetadata": { "action": { - "braketSchemaHeader": {"name": "braket.ir.openqasm.program", "version": "1"}, + "braketSchemaHeader": { + "name": "braket.ir.openqasm.program", + "version": "1", + }, "source": "qubit[2] q; cnot q[0], q[1]; measure q;", }, }, diff --git a/test/unit_tests/test_ahs_device.py b/test/unit_tests/test_ahs_device.py index e6781d7a..67fda630 100644 --- a/test/unit_tests/test_ahs_device.py +++ b/test/unit_tests/test_ahs_device.py @@ -28,7 +28,9 @@ from braket.ahs.shifting_field import ShiftingField from braket.aws import AwsDevice, AwsQuantumTask from braket.device_schema import DeviceActionProperties, DeviceActionType -from braket.device_schema.quera.quera_ahs_paradigm_properties_v1 import QueraAhsParadigmProperties +from braket.device_schema.quera.quera_ahs_paradigm_properties_v1 import ( + QueraAhsParadigmProperties, +) from braket.tasks.analog_hamiltonian_simulation_quantum_task_result import ShotResult from braket.tasks.local_quantum_task import LocalQuantumTask from braket.timings.time_series import TimeSeries @@ -104,14 +106,26 @@ def dummy_cfunc(t): HAMILTONIANS_AND_PARAMS = [ (H_i + rydberg_drive(amplitude=4, phase=1, detuning=3, wires=[0, 1, 2]), []), - (H_i + rydberg_drive(amplitude=amp, phase=1, detuning=2, wires=[0, 1, 2]), [params_amp]), - (H_i + rydberg_drive(amplitude=2, phase=f1, detuning=2, wires=[0, 1, 2]), [params1]), - (H_i + rydberg_drive(amplitude=2, phase=2, detuning=f2, wires=[0, 1, 2]), [params2]), + ( + H_i + rydberg_drive(amplitude=amp, phase=1, detuning=2, wires=[0, 1, 2]), + [params_amp], + ), + ( + H_i + rydberg_drive(amplitude=2, phase=f1, detuning=2, wires=[0, 1, 2]), + [params1], + ), + ( + H_i + rydberg_drive(amplitude=2, phase=2, detuning=f2, wires=[0, 1, 2]), + [params2], + ), ( H_i + rydberg_drive(amplitude=amp, phase=1, detuning=f2, wires=[0, 1, 2]), [params_amp, params2], ), - (H_i + rydberg_drive(amplitude=4, phase=f2, detuning=f1, wires=[0, 1, 2]), [params2, params1]), + ( + H_i + rydberg_drive(amplitude=4, phase=f2, detuning=f1, wires=[0, 1, 2]), + [params2, params1], + ), ( H_i + rydberg_drive(amplitude=amp, phase=f2, detuning=4, wires=[0, 1, 2]), [params_amp, params2], @@ -233,7 +247,9 @@ def mock_aws_device(monkeypatch, wires=3): """A function to create a mock device that mocks most of the methods""" with monkeypatch.context() as m: m.setattr( - AwsDevice, "_get_session_and_initialize", lambda self, *args, **kwargs: MockAwsSession + AwsDevice, + "_get_session_and_initialize", + lambda self, *args, **kwargs: MockAwsSession, ) m.setattr(AwsDevice, "properties", MockDevProperties) @@ -296,10 +312,22 @@ class DummyMeasurementResult: DUMMY_RESULTS = [ - (DummyMeasurementResult(Status("Success"), np.array([1]), np.array([1])), np.array([0])), - (DummyMeasurementResult(Status("Success"), np.array([1]), np.array([0])), np.array([1])), - (DummyMeasurementResult(Status("Success"), np.array([0]), np.array([0])), np.array([np.NaN])), - (DummyMeasurementResult(Status("Failure"), np.array([1]), np.array([1])), np.array([np.NaN])), + ( + DummyMeasurementResult(Status("Success"), np.array([1]), np.array([1])), + np.array([0]), + ), + ( + DummyMeasurementResult(Status("Success"), np.array([1]), np.array([0])), + np.array([1]), + ), + ( + DummyMeasurementResult(Status("Success"), np.array([0]), np.array([0])), + np.array([np.NaN]), + ), + ( + DummyMeasurementResult(Status("Failure"), np.array([1]), np.array([1])), + np.array([np.NaN]), + ), ( DummyMeasurementResult(Status("Success"), np.array([1, 1, 0]), np.array([1, 0, 0])), np.array([0, 1, np.NaN]), @@ -497,9 +525,18 @@ def test_create_ahs_program(self, hamiltonian, params): # elements of the hamiltonian have the expected shape h = ahs_program.hamiltonian - amp_time, amp_vals = h.amplitude.time_series.times(), h.amplitude.time_series.values() - phase_time, phase_vals = h.phase.time_series.times(), h.phase.time_series.values() - det_time, det_vals = h.detuning.time_series.times(), h.detuning.time_series.values() + amp_time, amp_vals = ( + h.amplitude.time_series.times(), + h.amplitude.time_series.values(), + ) + phase_time, phase_vals = ( + h.phase.time_series.times(), + h.phase.time_series.values(), + ) + det_time, det_vals = ( + h.detuning.time_series.times(), + h.detuning.time_series.values(), + ) assert amp_time == phase_time == det_time assert amp_time[0] == evolution.t[0] * 1e-6 @@ -700,7 +737,8 @@ def test_validate_operations_multiple_operators(self): op2 = qml.evolve(H_i + H1) with pytest.raises( - NotImplementedError, match="Support for multiple ParametrizedEvolution operators" + NotImplementedError, + match="Support for multiple ParametrizedEvolution operators", ): dev_sim._validate_operations([op1, op2]) @@ -1063,7 +1101,11 @@ def test_extract_pattern_from_detuning_negative_detuning(self, detunings): ([3, 2, 1], 3, [1, 2 / 3, 1 / 3]), ([lambda t: 2, dummy_cfunc, lambda t: 0], dummy_cfunc, [0.2, 1, 0]), ( - [sin_squared, lambda t: 0.5 * sin_squared(t), lambda t: 0.333 * sin_squared(t)], + [ + sin_squared, + lambda t: 0.5 * sin_squared(t), + lambda t: 0.333 * sin_squared(t), + ], sin_squared, [1, 0.5, 0.333], ), @@ -1086,7 +1128,11 @@ def test_extract_pattern_from_detunings(self, detunings, expected_max, expected_ "detunings, pattern", [ ( - [lambda t: sin_squared(t), lambda t: sin_squared(t), lambda t: 5 * sin_squared(t)], + [ + lambda t: sin_squared(t), + lambda t: sin_squared(t), + lambda t: 5 * sin_squared(t), + ], [0.2, 0.2, 1], ), ([1, 8.9, 10], [0.1, 0.89, 1]), @@ -1293,9 +1339,18 @@ def test_create_ahs_program(self, hamiltonian, params, mock_aws_device): # elements of the hamiltonian have the expected shape h = ahs_program.hamiltonian - amp_time, amp_vals = h.amplitude.time_series.times(), h.amplitude.time_series.values() - phase_time, phase_vals = h.phase.time_series.times(), h.phase.time_series.values() - det_time, det_vals = h.detuning.time_series.times(), h.detuning.time_series.values() + amp_time, amp_vals = ( + h.amplitude.time_series.times(), + h.amplitude.time_series.values(), + ) + phase_time, phase_vals = ( + h.phase.time_series.times(), + h.phase.time_series.values(), + ) + det_time, det_vals = ( + h.detuning.time_series.times(), + h.detuning.time_series.values(), + ) assert amp_time == phase_time == det_time assert float(amp_time[0]) == evolution.t[0] * 1e-6 @@ -1326,11 +1381,15 @@ def test_create_ahs_program(self, hamiltonian, params, mock_aws_device): p = params[params_idx] params_idx += 1 assert np.allclose( - [fn(p, float(t) * 1e6) for t in amp_time], [float(v) for v in phase_vals], atol=1e-7 + [fn(p, float(t) * 1e6) for t in amp_time], + [float(v) for v in phase_vals], + atol=1e-7, ) else: assert np.allclose( - [pulse.phase for t in amp_time], [float(v) for v in phase_vals], atol=1e-7 + [pulse.phase for t in amp_time], + [float(v) for v in phase_vals], + atol=1e-7, ) if callable(pulse.frequency): @@ -1343,7 +1402,8 @@ def test_create_ahs_program(self, hamiltonian, params, mock_aws_device): ) else: assert np.allclose( - [pulse.frequency * 2 * np.pi * 1e6 for t in amp_time], [float(v) for v in det_vals] + [pulse.frequency * 2 * np.pi * 1e6 for t in amp_time], + [float(v) for v in det_vals], ) def test_run_task(self, mock_aws_device): diff --git a/test/unit_tests/test_braket_device.py b/test/unit_tests/test_braket_device.py index 2b166717..a5fcc562 100644 --- a/test/unit_tests/test_braket_device.py +++ b/test/unit_tests/test_braket_device.py @@ -23,13 +23,22 @@ import pennylane as qml import pytest from braket.aws import AwsDevice, AwsDeviceType, AwsQuantumTask, AwsQuantumTaskBatch -from braket.circuits import Circuit, FreeParameter, Gate, Noise, observables, result_types +from braket.circuits import ( + Circuit, + FreeParameter, + Gate, + Noise, + observables, + result_types, +) from braket.circuits.noise_model import GateCriteria, NoiseModel, NoiseModelInstruction from braket.device_schema import DeviceActionType from braket.device_schema.gate_model_qpu_paradigm_properties_v1 import ( GateModelQpuParadigmProperties, ) -from braket.device_schema.pulse.pulse_device_action_properties_v1 import PulseDeviceActionProperties +from braket.device_schema.pulse.pulse_device_action_properties_v1 import ( + PulseDeviceActionProperties, +) from braket.device_schema.simulators import GateModelSimulatorDeviceCapabilities from braket.devices import LocalSimulator from braket.simulator import BraketSimulator @@ -135,7 +144,11 @@ def test_apply_unique_parameters(): def test_apply_unused_qubits(): """Tests that the correct circuit is created when not all wires in the device are used.""" dev = _aws_device(wires=4) - operations = [qml.Hadamard(wires=1), qml.CNOT(wires=[1, 2]), qml.RX(np.pi / 2, wires=2)] + operations = [ + qml.Hadamard(wires=1), + qml.CNOT(wires=[1, 2]), + qml.RX(np.pi / 2, wires=2), + ] rotations = [qml.RY(np.pi, wires=1)] circuit = dev.apply(operations, rotations) @@ -192,7 +205,8 @@ def test_execute(mock_run): results = dev.execute(circuit) assert np.allclose( - results[0], RESULT.get_value_by_result_type(result_types.Probability(target=[0])) + results[0], + RESULT.get_value_by_result_type(result_types.Probability(target=[0])), ) assert np.allclose( results[1], @@ -249,7 +263,8 @@ def test_execute_parametrize_differentiable(mock_run): results = dev._execute_legacy(circuit) assert np.allclose( - results[0], RESULT.get_value_by_result_type(result_types.Probability(target=[0])) + results[0], + RESULT.get_value_by_result_type(result_types.Probability(target=[0])), ) assert np.allclose( results[1], @@ -921,7 +936,8 @@ def test_aws_device_batch_execute_parallel(mock_run_batch): batch_results = dev.batch_execute(circuits) for results in batch_results: assert np.allclose( - results[0], RESULT.get_value_by_result_type(result_types.Probability(target=[0])) + results[0], + RESULT.get_value_by_result_type(result_types.Probability(target=[0])), ) assert np.allclose( results[1], @@ -971,7 +987,8 @@ def test_local_sim_batch_execute_parallel(mock_run_batch): batch_results = dev.batch_execute(circuits) for results in batch_results: assert np.allclose( - results[0], RESULT.get_value_by_result_type(result_types.Probability(target=[0])) + results[0], + RESULT.get_value_by_result_type(result_types.Probability(target=[0])), ) assert np.allclose( results[1], @@ -1183,7 +1200,11 @@ def test_execute_all_samples(mock_run): "measurements": [[0, 0, 1], [1, 0, 1], [1, 1, 0], [0, 0, 0]], "resultTypes": [ { - "type": {"observable": ["h", "i"], "targets": [0, 1], "type": "sample"}, + "type": { + "observable": ["h", "i"], + "targets": [0, 1], + "type": "sample", + }, "value": [1, -1, 1, 1], }, { @@ -1249,11 +1270,19 @@ def test_execute_some_samples(mock_run): "measurements": [[0, 0, 1], [1, 0, 1], [1, 1, 0], [0, 0, 0]], "resultTypes": [ { - "type": {"observable": ["h", "i"], "targets": [0, 1], "type": "sample"}, + "type": { + "observable": ["h", "i"], + "targets": [0, 1], + "type": "sample", + }, "value": [1, -1, 1, 1], }, { - "type": {"observable": ["z"], "targets": [2], "type": "expectation"}, + "type": { + "observable": ["z"], + "targets": [2], + "type": "expectation", + }, "value": 0.0, }, ], @@ -1310,7 +1339,11 @@ def test_execute_some_samples(mock_run): Counter({"00": 2, "11": 2}), [ { - "type": {"observable": ["z", "z"], "targets": [0, 1], "type": "sample"}, + "type": { + "observable": ["z", "z"], + "targets": [0, 1], + "type": "sample", + }, "value": [1, 1, 1, 1], }, ], @@ -1338,7 +1371,11 @@ def test_execute_some_samples(mock_run): Counter({"00": 2, "11": 2}), [ { - "type": {"observable": ["z", "z"], "targets": [0, 1], "type": "sample"}, + "type": { + "observable": ["z", "z"], + "targets": [0, 1], + "type": "sample", + }, "value": [1, 1, 1, 1], }, ], @@ -1706,7 +1743,11 @@ def test_add_braket_user_agent_invoked(aws_device_mock): {}, [ { - "type": {"observable": ["x"], "targets": [1], "type": "expectation"}, + "type": { + "observable": ["x"], + "targets": [1], + "type": "expectation", + }, "value": 0.0, } ], @@ -1798,7 +1839,11 @@ def test_execute_and_gradients( {"p_1": 0.543}, [ { - "type": {"observable": ["x", "y"], "targets": [0, 1], "type": "variance"}, + "type": { + "observable": ["x", "y"], + "targets": [0, 1], + "type": "variance", + }, "value": 0.0, } ], @@ -1891,7 +1936,12 @@ class DummyLocalQubitDevice(BraketQubitDevice): class DummyCircuitSimulator(BraketSimulator): def run( - self, program: ir.openqasm.Program, qubits: int, shots: Optional[int], *args, **kwargs + self, + program: ir.openqasm.Program, + qubits: int, + shots: Optional[int], + *args, + **kwargs, ) -> dict[str, Any]: self._shots = shots self._qubits = qubits @@ -2142,7 +2192,11 @@ def expected_braket_circuit_with_noise(): @patch.object(AwsDevice, "run") @patch.object(AwsDevice, "name", new_callable=mock.PropertyMock) def test_execute_with_noise_model( - mock_name, mock_run, noise_model, pennylane_quantum_tape, expected_braket_circuit_with_noise + mock_name, + mock_run, + noise_model, + pennylane_quantum_tape, + expected_braket_circuit_with_noise, ): mock_run.return_value = TASK mock_name.return_value = "dm1" diff --git a/test/unit_tests/test_shadow_expval.py b/test/unit_tests/test_shadow_expval.py index d50393f5..4dcc6237 100644 --- a/test/unit_tests/test_shadow_expval.py +++ b/test/unit_tests/test_shadow_expval.py @@ -9,7 +9,9 @@ from braket.aws import AwsDevice, AwsDeviceType, AwsQuantumTask from braket.circuits import Circuit from braket.device_schema import DeviceActionType -from braket.device_schema.openqasm_device_action_properties import OpenQASMDeviceActionProperties +from braket.device_schema.openqasm_device_action_properties import ( + OpenQASMDeviceActionProperties, +) from braket.device_schema.simulators import GateModelSimulatorDeviceCapabilities from braket.devices import LocalSimulator from braket.simulator import BraketSimulator @@ -33,7 +35,12 @@ "version": ["1"], "supportedOperations": ["rx", "ry", "h", "cy", "cnot", "unitary"], "supportedResultTypes": [ - {"name": "StateVector", "observables": None, "minShots": 0, "maxShots": 0}, + { + "name": "StateVector", + "observables": None, + "minShots": 0, + "maxShots": 0, + }, { "name": "AdjointGradient", "observables": ["x", "y", "z", "h", "i"], @@ -52,14 +59,20 @@ "measurements": SNAPSHOTS, "measuredQubits": [0, 1], "taskMetadata": { - "braketSchemaHeader": {"name": "braket.task_result.task_metadata", "version": "1"}, + "braketSchemaHeader": { + "name": "braket.task_result.task_metadata", + "version": "1", + }, "id": "task_arn", "shots": SHOTS, "deviceId": "default", }, "additionalMetadata": { "action": { - "braketSchemaHeader": {"name": "braket.ir.openqasm.program", "version": "1"}, + "braketSchemaHeader": { + "name": "braket.ir.openqasm.program", + "version": "1", + }, "source": "qubit[2] q; cnot q[0], q[1]; measure q;", }, }, @@ -77,14 +90,20 @@ "resultTypes": [], "measuredQubits": [0, 1], "taskMetadata": { - "braketSchemaHeader": {"name": "braket.task_result.task_metadata", "version": "1"}, + "braketSchemaHeader": { + "name": "braket.task_result.task_metadata", + "version": "1", + }, "id": "task_arn", "shots": 1, "deviceId": "default", }, "additionalMetadata": { "action": { - "braketSchemaHeader": {"name": "braket.ir.openqasm.program", "version": "1"}, + "braketSchemaHeader": { + "name": "braket.ir.openqasm.program", + "version": "1", + }, "source": "qubit[2] q; cnot q[0], q[1]; measure q;", }, }, @@ -103,14 +122,20 @@ "resultTypes": [], "measuredQubits": [0, 1], "taskMetadata": { - "braketSchemaHeader": {"name": "braket.task_result.task_metadata", "version": "1"}, + "braketSchemaHeader": { + "name": "braket.task_result.task_metadata", + "version": "1", + }, "id": "task_arn", "shots": 1, "deviceId": "default", }, "additionalMetadata": { "action": { - "braketSchemaHeader": {"name": "braket.ir.openqasm.program", "version": "1"}, + "braketSchemaHeader": { + "name": "braket.ir.openqasm.program", + "version": "1", + }, "source": "qubit[2] q; cnot q[0], q[1]; measure q;", }, }, @@ -128,14 +153,20 @@ "resultTypes": [], "measuredQubits": [0, 1], "taskMetadata": { - "braketSchemaHeader": {"name": "braket.task_result.task_metadata", "version": "1"}, + "braketSchemaHeader": { + "name": "braket.task_result.task_metadata", + "version": "1", + }, "id": "task_arn", "shots": 1, "deviceId": "default", }, "additionalMetadata": { "action": { - "braketSchemaHeader": {"name": "braket.ir.openqasm.program", "version": "1"}, + "braketSchemaHeader": { + "name": "braket.ir.openqasm.program", + "version": "1", + }, "source": "qubit[2] q; cnot q[0], q[1]; measure q;", }, }, @@ -228,7 +259,11 @@ def test_shadow_expval_aws_device( max_conn, ): dev = _aws_device( - wires=2, foo="bar", parallel=parallel, max_parallel=max_para, max_connections=max_conn + wires=2, + foo="bar", + parallel=parallel, + max_parallel=max_para, + max_connections=max_conn, ) mock_runner = mock_run_batch if parallel else mock_run mock_runner.return_value = return_val @@ -351,7 +386,12 @@ class DummyLocalQubitDevice(BraketQubitDevice): class DummyCircuitSimulator(BraketSimulator): def run( - self, program: ir.openqasm.Program, qubits: int, shots: Optional[int], *args, **kwargs + self, + program: ir.openqasm.Program, + qubits: int, + shots: Optional[int], + *args, + **kwargs, ) -> dict[str, Any]: self._shots = shots self._qubits = qubits @@ -463,7 +503,10 @@ def test_shadows_parallel_tracker(mock_run_batch): class DummyMeasurementTransform(MeasurementTransform): def __init__( - self, wires: Optional[Wires] = None, seed: Optional[int] = None, id: Optional[str] = None + self, + wires: Optional[Wires] = None, + seed: Optional[int] = None, + id: Optional[str] = None, ): self.seed = seed super().__init__(wires=wires, id=id) diff --git a/test/unit_tests/test_translation.py b/test/unit_tests/test_translation.py index 98e97f1b..5c719e68 100644 --- a/test/unit_tests/test_translation.py +++ b/test/unit_tests/test_translation.py @@ -35,7 +35,9 @@ from braket.device_schema.gate_model_qpu_paradigm_properties_v1 import ( GateModelQpuParadigmProperties, ) -from braket.device_schema.pulse.pulse_device_action_properties_v1 import PulseDeviceActionProperties +from braket.device_schema.pulse.pulse_device_action_properties_v1 import ( + PulseDeviceActionProperties, +) from braket.pulse import ArbitraryWaveform, ConstantWaveform from braket.tasks import GateModelQuantumTaskResult from device_property_jsons import ( @@ -150,7 +152,12 @@ def _aws_device( (qml.IsingYY, gates.YY, [0, 1], [np.pi]), (qml.IsingZZ, gates.ZZ, [0, 1], [np.pi]), (qml.AmplitudeDamping, noises.AmplitudeDamping, [0], [0.1]), - (qml.GeneralizedAmplitudeDamping, noises.GeneralizedAmplitudeDamping, [0], [0.1, 0.15]), + ( + qml.GeneralizedAmplitudeDamping, + noises.GeneralizedAmplitudeDamping, + [0], + [0.1, 0.15], + ), (qml.PhaseDamping, noises.PhaseDamping, [0], [0.1]), (qml.DepolarizingChannel, noises.Depolarizing, [0], [0.1]), (qml.BitFlip, noises.BitFlip, [0], [0.1]), @@ -189,14 +196,16 @@ def _aws_device( 1 / np.sqrt(2) * np.array( - [[1, 0, 0, 1j], [0, 1j, 1, 0], [0, 1j, -1, 0], [1, 0, 0, -1j]], dtype=complex + [[1, 0, 0, 1j], [0, 1j, 1, 0], [0, 1j, -1, 0], [1, 0, 0, -1j]], + dtype=complex, ) ], [ 1 / np.sqrt(2) * np.array( - [[1, 0, 0, 1], [0, -1j, -1j, 0], [0, 1, -1, 0], [-1j, 0, 0, 1j]], dtype=complex + [[1, 0, 0, 1], [0, -1j, -1j, 0], [0, 1, -1, 0], [-1j, 0, 0, 1j]], + dtype=complex, ) ], ), @@ -242,13 +251,48 @@ def _aws_device( (qml.SWAP, gates.Swap, [0, 1], [], [], []), (qml.CSWAP, gates.CSwap, [0, 1, 2], [], [], []), (qml.Toffoli, gates.CCNot, [0, 1, 2], [], [], []), - (qml.ControlledPhaseShift, gates.CPhaseShift, [0, 1], [np.pi], ["pi"], [FreeParameter("pi")]), - (CPhaseShift00, gates.CPhaseShift00, [0, 1], [np.pi], ["pi"], [FreeParameter("pi")]), - (CPhaseShift01, gates.CPhaseShift01, [0, 1], [np.pi], ["pi"], [FreeParameter("pi")]), - (CPhaseShift10, gates.CPhaseShift10, [0, 1], [np.pi], ["pi"], [FreeParameter("pi")]), + ( + qml.ControlledPhaseShift, + gates.CPhaseShift, + [0, 1], + [np.pi], + ["pi"], + [FreeParameter("pi")], + ), + ( + CPhaseShift00, + gates.CPhaseShift00, + [0, 1], + [np.pi], + ["pi"], + [FreeParameter("pi")], + ), + ( + CPhaseShift01, + gates.CPhaseShift01, + [0, 1], + [np.pi], + ["pi"], + [FreeParameter("pi")], + ), + ( + CPhaseShift10, + gates.CPhaseShift10, + [0, 1], + [np.pi], + ["pi"], + [FreeParameter("pi")], + ), (GPi, gates.GPi, [0], [2], ["a"], [FreeParameter("a")]), (GPi2, gates.GPi2, [0], [2], ["a"], [FreeParameter("a")]), - (MS, gates.MS, [0, 1], [2, 3], ["a", "c"], [FreeParameter("a"), FreeParameter("c")]), + ( + MS, + gates.MS, + [0, 1], + [2, 3], + ["a", "c"], + [FreeParameter("a"), FreeParameter("c")], + ), ( AAMS, gates.MS, @@ -281,7 +325,14 @@ def _aws_device( [FreeParameter("p_000"), FreeParameter("p_001")], ), (qml.PhaseDamping, noises.PhaseDamping, [0], [0.1], ["a"], [FreeParameter("a")]), - (qml.DepolarizingChannel, noises.Depolarizing, [0], [0.1], ["a"], [FreeParameter("a")]), + ( + qml.DepolarizingChannel, + noises.Depolarizing, + [0], + [0.1], + ["a"], + [FreeParameter("a")], + ), (qml.BitFlip, noises.BitFlip, [0], [0.1], ["a"], [FreeParameter("a")]), (qml.PhaseFlip, noises.PhaseFlip, [0], [0.1], ["a"], [FreeParameter("a")]), ( @@ -623,7 +674,8 @@ def test_translate_operation_iswap_inverse(): def test_translate_operation_param_names_wrong_length(): """Tests that translation fails if provided param_names list is the wrong length""" with pytest.raises( - ValueError, match="Parameter names list must be equal to number of operation parameters" + ValueError, + match="Parameter names list must be equal to number of operation parameters", ): translate_operation(qml.RX(0.432, wires=0), use_unique_params=True, param_names=["a", "b"]) @@ -684,7 +736,10 @@ def test_translate_result_type_hamiltonian_expectation(): obs = qml.Hamiltonian((2, 3), (qml.PauliX(wires=0), qml.PauliY(wires=1))) tape = qml.tape.QuantumTape(measurements=[qml.expval(obs)]) braket_result_type_calculated = translate_result_type(tape.measurements[0], [0], frozenset()) - braket_result_type = (Expectation(observables.X(), [0]), Expectation(observables.Y(), [1])) + braket_result_type = ( + Expectation(observables.X(), [0]), + Expectation(observables.Y(), [1]), + ) assert braket_result_type == braket_result_type_calculated @@ -788,7 +843,11 @@ def test_translate_result_hamiltonian(): result_dict = _result_meta() result_dict["resultTypes"] = [ { - "type": {"observable": ["x", "y"], "targets": [0, 1], "type": "expectation"}, + "type": { + "observable": ["x", "y"], + "targets": [0, 1], + "type": "expectation", + }, "value": 2.0, }, { @@ -813,14 +872,20 @@ def _result_meta() -> dict: "version": "1", }, "taskMetadata": { - "braketSchemaHeader": {"name": "braket.task_result.task_metadata", "version": "1"}, + "braketSchemaHeader": { + "name": "braket.task_result.task_metadata", + "version": "1", + }, "id": "task_arn", "shots": 0, "deviceId": "default", }, "additionalMetadata": { "action": { - "braketSchemaHeader": {"name": "braket.ir.jaqcd.program", "version": "1"}, + "braketSchemaHeader": { + "name": "braket.ir.jaqcd.program", + "version": "1", + }, "instructions": [{"control": 0, "target": 1, "type": "cnot"}], }, }, @@ -844,8 +909,14 @@ def _result_meta() -> dict: + 0.75 * qml.PauliX(0), ), (1.25 * observables.H(0), 1.25 * qml.Hadamard(wires=0)), - (observables.X(0) @ observables.Y(1), qml.ops.Prod(qml.PauliX(0), qml.PauliY(1))), - (observables.X(0) + observables.Y(1), qml.ops.Sum(qml.PauliX(0), qml.PauliY(1))), + ( + observables.X(0) @ observables.Y(1), + qml.ops.Prod(qml.PauliX(0), qml.PauliY(1)), + ), + ( + observables.X(0) + observables.Y(1), + qml.ops.Sum(qml.PauliX(0), qml.PauliY(1)), + ), (observables.X(0), qml.ops.SProd(scalar=4, base=qml.PauliX(0))), ], ) diff --git a/tox.ini b/tox.ini index b5ee8bbc..5bf7eac9 100644 --- a/tox.ini +++ b/tox.ini @@ -39,69 +39,39 @@ extras = test [testenv:linters] basepython = python3 skip_install = true +# Remove this to check what versions are installed for the env. This stops running pip freeze. +list_dependencies_command = echo deps = - {[testenv:isort]deps} - {[testenv:black]deps} - {[testenv:flake8]deps} + {[testenv:ruff-format]deps} + {[testenv:ruff-check]deps} commands = - # isort MUST come before black as it will revert any changes made by black - {[testenv:isort]commands} - {[testenv:black]commands} - {[testenv:flake8]commands} - -[testenv:flake8] -basepython = python3 -skip_install = true -deps = - flake8 - flake8-rst-docstrings -commands = - flake8 {posargs} - -[testenv:isort] -basepython = python3 -skip_install = true -deps = - isort -commands = - isort -rc . {posargs} - -[testenv:black] -basepython = python3 -skip_install = true -deps = - black -commands = - black ./ {posargs} + {[testenv:ruff-format]commands} + {[testenv:ruff-check]commands} # Read only linter env [testenv:linters_check] basepython = python3 skip_install = true deps = - {[testenv:isort_check]deps} - {[testenv:black_check]deps} - {[testenv:flake8]deps} + {[testenv:ruff-check]deps} commands = - {[testenv:isort_check]commands} - {[testenv:black_check]commands} - {[testenv:flake8]commands} + {[testenv:ruff-check]commands} -[testenv:isort_check] +[testenv:ruff-check] basepython = python3 skip_install = true deps = - isort + ruff commands = - isort . -c {posargs} + ruff check src {posargs} -[testenv:black_check] +[testenv:ruff-format] basepython = python3 skip_install = true deps = - black + ruff commands = - black --check . {posargs} + ruff format . {posargs} [testenv:docs] basepython = python3