From 785d2512535af9606fd66eedd4476984c7b41a8b Mon Sep 17 00:00:00 2001 From: Altanali Date: Wed, 26 Jun 2024 13:53:16 -0700 Subject: [PATCH 01/15] feat: Track classical target indices for measurements (#1008) --- src/braket/circuits/braket_program_context.py | 14 ++++++++------ src/braket/circuits/circuit.py | 9 +++++---- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/braket/circuits/braket_program_context.py b/src/braket/circuits/braket_program_context.py index 4371637d3..558692510 100644 --- a/src/braket/circuits/braket_program_context.py +++ b/src/braket/circuits/braket_program_context.py @@ -11,6 +11,7 @@ # ANY KIND, either express or implied. See the License for the specific # language governing permissions and limitations under the License. +from collections.abc import Iterable from typing import Optional, Union import numpy as np @@ -161,16 +162,17 @@ def handle_parameter_value( return FreeParameterExpression(evaluated_value) return value - def add_measure(self, target: tuple[int]) -> None: + def add_measure( + self, target: tuple[int], classical_targets: Optional[Iterable[int]] = None + ) -> None: """Add a measure instruction to the circuit Args: target (tuple[int]): the target qubits to be measured. + classical_targets (Optional[Iterable[int]]): the classical registers + to use in the qubit measurement. """ - for index, qubit in enumerate(target): + for iter, qubit in enumerate(target): + index = classical_targets[iter] if classical_targets else iter instruction = Instruction(Measure(index=index), qubit) self._circuit.add_instruction(instruction) - if self._circuit._measure_targets: - self._circuit._measure_targets.append(qubit) - else: - self._circuit._measure_targets = [qubit] diff --git a/src/braket/circuits/circuit.py b/src/braket/circuits/circuit.py index f15e03647..9ce7df7f8 100644 --- a/src/braket/circuits/circuit.py +++ b/src/braket/circuits/circuit.py @@ -504,6 +504,11 @@ def add_instruction( # Check if there is a measure instruction on the circuit self._check_if_qubit_measured(instruction, target, target_mapping) + # Update measure targets if instruction is a measurement + if isinstance(instruction.operator, Measure): + measure_target = target or instruction.target[0] + self._measure_targets = (self._measure_targets or []) + [measure_target] + if not target_mapping and not target: # Nothing has been supplied, add instruction instructions_to_add = [instruction] @@ -710,10 +715,6 @@ def _add_measure(self, target_qubits: QubitSetInput) -> None: target=target, ) ) - if self._measure_targets: - self._measure_targets.append(target) - else: - self._measure_targets = [target] def measure(self, target_qubits: QubitSetInput) -> Circuit: """ From eeb7630e5b876b9cb1c3c7a856b66dc0c2c2e4ec Mon Sep 17 00:00:00 2001 From: Altanali Date: Wed, 26 Jun 2024 16:47:54 -0700 Subject: [PATCH 02/15] change: Add test to check classical indices used in measurement are preserved between Circuit and OpenQASM Translations. (#1013) --- setup.py | 2 +- .../braket/circuits/test_circuit.py | 29 +++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 43d2c52ad..54987c283 100644 --- a/setup.py +++ b/setup.py @@ -28,7 +28,7 @@ package_dir={"": "src"}, install_requires=[ "amazon-braket-schemas>=1.21.3", - "amazon-braket-default-simulator>=1.21.4", + "amazon-braket-default-simulator>=1.25.0", "oqpy~=0.3.5", "backoff", "boltons", diff --git a/test/unit_tests/braket/circuits/test_circuit.py b/test/unit_tests/braket/circuits/test_circuit.py index 71eecd1f1..897828b27 100644 --- a/test/unit_tests/braket/circuits/test_circuit.py +++ b/test/unit_tests/braket/circuits/test_circuit.py @@ -3610,3 +3610,32 @@ def test_circuit_with_global_phase(): "b[0] = measure $0;", ] ) + + +def test_from_ir_round_trip_transformation_with_targeted_measurements(): + circuit = ( + Circuit() + .h(0) + .cnot(0, 1) + .add_instruction(Instruction(Measure(index=2), 1)) + .add_instruction(Instruction(Measure(index=1), 2)) + .add_instruction(Instruction(Measure(index=0), 0)) + ) + ir = OpenQasmProgram( + source="\n".join( + [ + "OPENQASM 3.0;", + "bit[3] b;", + "qubit[3] q;", + "h q[0];", + "cnot q[0], q[1];", + "b[2] = measure q[1];", + "b[1] = measure q[2];", + "b[0] = measure q[0];", + ] + ), + inputs={}, + ) + + assert Circuit.from_ir(ir) == Circuit.from_ir(circuit.to_ir("OPENQASM")) + assert circuit.to_ir("OPENQASM") == Circuit.from_ir(ir).to_ir("OPENQASM") From 6cd842e081300369583974e54caa6509cf3eb90a Mon Sep 17 00:00:00 2001 From: ci Date: Thu, 27 Jun 2024 00:03:09 +0000 Subject: [PATCH 03/15] prepare release v1.82.0 --- CHANGELOG.md | 10 ++++++++++ src/braket/_sdk/_version.py | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 82e97333d..f6716703f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # Changelog +## v1.82.0 (2024-06-27) + +### Features + + * Track classical target indices for measurements + +### Bug Fixes and Other Changes + + * Add test to check classical indices used in measurement are preserved between Circuit and OpenQASM Translations. + ## v1.81.1 (2024-06-17) ### Bug Fixes and Other Changes diff --git a/src/braket/_sdk/_version.py b/src/braket/_sdk/_version.py index 50ee98c7c..1ce2d2394 100644 --- a/src/braket/_sdk/_version.py +++ b/src/braket/_sdk/_version.py @@ -15,4 +15,4 @@ Version number (major.minor.patch[-label]) """ -__version__ = "1.81.2.dev0" +__version__ = "1.82.0" From 239fc81f1dcb7bc298fceca73babdef12281d969 Mon Sep 17 00:00:00 2001 From: ci Date: Thu, 27 Jun 2024 00:03:09 +0000 Subject: [PATCH 04/15] update development version to v1.82.1.dev0 --- src/braket/_sdk/_version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/braket/_sdk/_version.py b/src/braket/_sdk/_version.py index 1ce2d2394..4d28af096 100644 --- a/src/braket/_sdk/_version.py +++ b/src/braket/_sdk/_version.py @@ -15,4 +15,4 @@ Version number (major.minor.patch[-label]) """ -__version__ = "1.82.0" +__version__ = "1.82.1.dev0" From 12d0d670bd80427c1b633461cef3bc49c3f2f152 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 27 Jun 2024 14:33:35 -0700 Subject: [PATCH 05/15] infra: bump actions/setup-python from 5.0.0 to 5.1.0 (#931) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Cody Wang --- .github/workflows/check-format.yml | 2 +- .github/workflows/dependent-tests.yml | 2 +- .github/workflows/publish-to-pypi.yml | 2 +- .github/workflows/python-package.yml | 2 +- .github/workflows/twine-check.yml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/check-format.yml b/.github/workflows/check-format.yml index a6106b2d7..dfdb535b1 100644 --- a/.github/workflows/check-format.yml +++ b/.github/workflows/check-format.yml @@ -18,7 +18,7 @@ jobs: steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Set up Python - uses: actions/setup-python@0a5c61591373683505ea898e09a3ea4f39ef2b9c # v5.0.0 + uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0 with: python-version: '3.9' - name: Install dependencies diff --git a/.github/workflows/dependent-tests.yml b/.github/workflows/dependent-tests.yml index aca79d599..1ba9dd26a 100644 --- a/.github/workflows/dependent-tests.yml +++ b/.github/workflows/dependent-tests.yml @@ -23,7 +23,7 @@ jobs: steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@0a5c61591373683505ea898e09a3ea4f39ef2b9c # v5.0.0 + uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0 with: python-version: ${{ matrix.python-version }} - name: Install dependencies diff --git a/.github/workflows/publish-to-pypi.yml b/.github/workflows/publish-to-pypi.yml index a6a359e93..fa07100e9 100644 --- a/.github/workflows/publish-to-pypi.yml +++ b/.github/workflows/publish-to-pypi.yml @@ -14,7 +14,7 @@ jobs: steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Set up Python - uses: actions/setup-python@0a5c61591373683505ea898e09a3ea4f39ef2b9c # v5.0.0 + uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0 with: python-version: '3.x' - name: Install wheel diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 9d398f23d..147a1ce24 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -26,7 +26,7 @@ jobs: steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@0a5c61591373683505ea898e09a3ea4f39ef2b9c # v5.0.0 + uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0 with: python-version: ${{ matrix.python-version }} - name: Install dependencies diff --git a/.github/workflows/twine-check.yml b/.github/workflows/twine-check.yml index 2c30b8ec0..2d48fcc1d 100644 --- a/.github/workflows/twine-check.yml +++ b/.github/workflows/twine-check.yml @@ -16,7 +16,7 @@ jobs: steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Set up Python - uses: actions/setup-python@0a5c61591373683505ea898e09a3ea4f39ef2b9c # v5.0.0 + uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0 with: python-version: '3.x' - name: Install wheel From 24d4d5f03c410cee8f46f73f99c39a0ece99327e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 27 Jun 2024 14:41:02 -0700 Subject: [PATCH 06/15] infra: bump actions/checkout from 4.1.1 to 4.1.5 (#967) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/check-format.yml | 2 +- .github/workflows/dependent-tests.yml | 2 +- .github/workflows/publish-to-pypi.yml | 2 +- .github/workflows/python-package.yml | 2 +- .github/workflows/twine-check.yml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/check-format.yml b/.github/workflows/check-format.yml index dfdb535b1..942e35cc9 100644 --- a/.github/workflows/check-format.yml +++ b/.github/workflows/check-format.yml @@ -16,7 +16,7 @@ jobs: check-code-format: runs-on: ubuntu-latest steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5 - name: Set up Python uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0 with: diff --git a/.github/workflows/dependent-tests.yml b/.github/workflows/dependent-tests.yml index 1ba9dd26a..cfb58c2f8 100644 --- a/.github/workflows/dependent-tests.yml +++ b/.github/workflows/dependent-tests.yml @@ -21,7 +21,7 @@ jobs: - amazon-braket-pennylane-plugin-python steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0 with: diff --git a/.github/workflows/publish-to-pypi.yml b/.github/workflows/publish-to-pypi.yml index fa07100e9..c1de37678 100644 --- a/.github/workflows/publish-to-pypi.yml +++ b/.github/workflows/publish-to-pypi.yml @@ -12,7 +12,7 @@ jobs: name: Build and publish distribution to PyPi runs-on: ubuntu-latest steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5 - name: Set up Python uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0 with: diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 147a1ce24..2f6b9992b 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -24,7 +24,7 @@ jobs: python-version: ["3.9", "3.10", "3.11"] steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0 with: diff --git a/.github/workflows/twine-check.yml b/.github/workflows/twine-check.yml index 2d48fcc1d..b3bd97833 100644 --- a/.github/workflows/twine-check.yml +++ b/.github/workflows/twine-check.yml @@ -14,7 +14,7 @@ jobs: name: Check long description runs-on: ubuntu-latest steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5 - name: Set up Python uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0 with: From 96b42001e95ed6ccaeb78087dcec61fe03022044 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 27 Jun 2024 14:44:59 -0700 Subject: [PATCH 07/15] infra: bump pypa/gh-action-pypi-publish from 1.8.14 to 1.9.0 (#1012) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/publish-to-pypi.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish-to-pypi.yml b/.github/workflows/publish-to-pypi.yml index c1de37678..129f2f9f7 100644 --- a/.github/workflows/publish-to-pypi.yml +++ b/.github/workflows/publish-to-pypi.yml @@ -26,6 +26,6 @@ jobs: - name: Build a binary wheel and a source tarball run: python setup.py sdist bdist_wheel - name: Publish distribution to PyPI - uses: pypa/gh-action-pypi-publish@81e9d935c883d0b210363ab89cf05f3894778450 # release/v1 + uses: pypa/gh-action-pypi-publish@ec4db0b4ddc65acdf4bff5fa45ac92d78b56bdf0 # release/v1 with: password: ${{ secrets.pypi_token }} From fb307e325aea716e56c888cc6e4ed6394bf90b6d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 27 Jun 2024 14:50:09 -0700 Subject: [PATCH 08/15] infra: bump thehanimo/pr-title-checker from 1.4.1 to 1.4.2 (#1010) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/pr-title-checker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pr-title-checker.yml b/.github/workflows/pr-title-checker.yml index a20344a77..78126bdce 100644 --- a/.github/workflows/pr-title-checker.yml +++ b/.github/workflows/pr-title-checker.yml @@ -24,7 +24,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "Check PR Title" - uses: thehanimo/pr-title-checker@v1.4.1 + uses: thehanimo/pr-title-checker@v1.4.2 with: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} pass_on_octokit_error: false From 9f6adcf11f0778f7fe096236ef7bd9011ef30687 Mon Sep 17 00:00:00 2001 From: Ryan Shaffer <3620100+rmshaffer@users.noreply.github.com> Date: Thu, 27 Jun 2024 17:53:54 -0400 Subject: [PATCH 09/15] doc: update PR title instructions (#994) --- .github/pull_request_template.md | 2 +- CONTRIBUTING.md | 22 ++++++++++------------ 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 87dda8a1f..d4fb6616f 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -11,7 +11,7 @@ _Put an `x` in the boxes that apply. You can also fill these out after creating #### General - [ ] I have read the [CONTRIBUTING](https://github.com/amazon-braket/amazon-braket-sdk-python/blob/main/CONTRIBUTING.md) doc -- [ ] I used the commit message format described in [CONTRIBUTING](https://github.com/amazon-braket/amazon-braket-sdk-python/blob/main/CONTRIBUTING.md#commit-your-change) +- [ ] I used the PR title format described in [CONTRIBUTING](https://github.com/amazon-braket/amazon-braket-sdk-python/blob/main/CONTRIBUTING.md#PR-title-format) - [ ] I have updated any necessary documentation, including [READMEs](https://github.com/amazon-braket/amazon-braket-sdk-python/blob/main/README.md) and [API docs](https://github.com/amazon-braket/amazon-braket-sdk-python/blob/main/CONTRIBUTING.md#documentation-guidelines) (if appropriate) #### Tests diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0df22f51e..5635cd689 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -95,10 +95,18 @@ You can also pass in various pytest arguments `tox -e integ-tests -- your-argume 1. Run `tox`, to run all the unit tests, linters, and documentation creation, and verify that all checks and tests pass. 1. If your changes include documentation changes, please see the [Documentation Guidelines](#documentation-guidelines). +### Send a Pull Request + +GitHub provides additional documentation on [Creating a Pull Request](https://help.github.com/articles/creating-a-pull-request/). + +Please remember to: +* Use PR titles that follow the guidelines under [PR Title Format](#pr-title-format). +* Send us a pull request, answering any default questions in the pull request interface. +* Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation. -### Commit Your Change +#### PR Title Format -We use commit messages to update the project version number and generate changelog entries, so it's important for them to follow the right format. Valid commit messages include a prefix, separated from the rest of the message by a colon and a space. Here are a few examples: +We use commit messages to update the project version number and generate changelog entries. The PR title is used as the commit message when merging a PR, so it's important for PR titles to follow the right format. Valid PR titles include a prefix, separated from the rest of the message by a colon and a space. Here are a few examples: ``` feature: support new parameter for `xyz` @@ -122,16 +130,6 @@ Some of the prefixes allow abbreviation ; `break`, `feat`, `depr`, and `doc` are For the rest of the message, use imperative style and keep things concise but informative. See [How to Write a Git Commit Message](https://chris.beams.io/posts/git-commit/) for guidance. -### Send a Pull Request - -GitHub provides additional documentation on [Creating a Pull Request](https://help.github.com/articles/creating-a-pull-request/). - -Please remember to: -* Use commit messages (and PR titles) that follow the guidelines under [Commit Your Change](#commit-your-change). -* Send us a pull request, answering any default questions in the pull request interface. -* Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation. - - ```mermaid timeline title Code integration journey (CI) From dabcb5e622487f5b49335249cadc2c221ec03602 Mon Sep 17 00:00:00 2001 From: Cody Wang Date: Fri, 28 Jun 2024 11:23:48 -0700 Subject: [PATCH 10/15] feat: Use `run_multiple` for local batches (#1005) The Braket SDK can now leverage custom backend implementations for running multiple tasks --- setup.py | 2 +- src/braket/devices/device.py | 2 +- src/braket/devices/local_simulator.py | 175 +++++++----------- .../braket/devices/test_local_simulator.py | 19 +- 4 files changed, 80 insertions(+), 118 deletions(-) diff --git a/setup.py b/setup.py index 54987c283..bf429b266 100644 --- a/setup.py +++ b/setup.py @@ -28,7 +28,7 @@ package_dir={"": "src"}, install_requires=[ "amazon-braket-schemas>=1.21.3", - "amazon-braket-default-simulator>=1.25.0", + "amazon-braket-default-simulator>=1.26.0", "oqpy~=0.3.5", "backoff", "boltons", diff --git a/src/braket/devices/device.py b/src/braket/devices/device.py index dbc7b6b35..af3467a40 100644 --- a/src/braket/devices/device.py +++ b/src/braket/devices/device.py @@ -131,7 +131,7 @@ def _validate_device_noise_model_support(self, noise_model: NoiseModel) -> None: def _apply_noise_model_to_circuit( self, task_specification: Union[Circuit, Problem, Program, AnalogHamiltonianSimulation] - ) -> None: + ) -> Union[Circuit, Problem, Program, AnalogHamiltonianSimulation]: if isinstance(task_specification, Circuit): for instruction in task_specification.instructions: if isinstance(instruction.operator, Noise): diff --git a/src/braket/devices/local_simulator.py b/src/braket/devices/local_simulator.py index 15ec904de..02b379596 100644 --- a/src/braket/devices/local_simulator.py +++ b/src/braket/devices/local_simulator.py @@ -16,7 +16,6 @@ import sys from functools import singledispatchmethod from itertools import repeat -from multiprocessing import Pool from os import cpu_count from typing import Any, Optional, Union @@ -31,6 +30,11 @@ from braket.ir.ahs import Program as AHSProgram from braket.ir.openqasm import Program as OpenQASMProgram from braket.simulator import BraketSimulator +from braket.task_result import ( + AnalogHamiltonianSimulationTaskResult, + AnnealingTaskResult, + GateModelTaskResult, +) from braket.tasks import AnnealingQuantumTaskResult, GateModelQuantumTaskResult from braket.tasks.analog_hamiltonian_simulation_quantum_task_result import ( AnalogHamiltonianSimulationQuantumTaskResult, @@ -118,8 +122,9 @@ def run( """ if self._noise_model: task_specification = self._apply_noise_model_to_circuit(task_specification) - result = self._run_internal(task_specification, shots, inputs=inputs, *args, **kwargs) - return LocalQuantumTask(result) + payload = self._construct_payload(task_specification, inputs, shots) + result = self._delegate.run(payload, *args, shots=shots, **kwargs) + return LocalQuantumTask(self._to_result_object(result)) def run_batch( # noqa: C901 self, @@ -151,7 +156,7 @@ def run_batch( # noqa: C901 shots (Optional[int]): The number of times to run the quantum task. Default: 0. max_parallel (Optional[int]): The maximum number of quantum tasks to run in parallel. Default - is the number of CPU. + is the number of logical CPUs. inputs (Optional[Union[dict[str, float], list[dict[str, float]]]]): Inputs to be passed along with the IR. If the IR supports inputs, the inputs will be updated with this value. Default: {}. @@ -195,6 +200,7 @@ def run_batch( # noqa: C901 else: tasks_and_inputs = list(tasks_and_inputs) + payloads = [] for task_specification, input_map in tasks_and_inputs: if isinstance(task_specification, Circuit): param_names = {param.name for param in task_specification.parameters} @@ -203,12 +209,12 @@ def run_batch( # noqa: C901 f"Cannot execute circuit with unbound parameters: " f"{unbounded_parameters}" ) + payloads.append(self._construct_payload(task_specification, input_map, shots)) - with Pool(min(max_parallel, len(tasks_and_inputs))) as pool: - param_list = [(task, shots, inp, *args, *kwargs) for task, inp in tasks_and_inputs] - results = pool.starmap(self._run_internal_wrap, param_list) - - return LocalQuantumTaskBatch(results) + results = self._delegate.run_multiple( + payloads, *args, shots=shots, max_parallel=max_parallel, **kwargs + ) + return LocalQuantumTaskBatch([self._to_result_object(result) for result in results]) @property def properties(self) -> DeviceCapabilities: @@ -230,21 +236,8 @@ def registered_backends() -> set[str]: """ return set(_simulator_devices.keys()) - def _run_internal_wrap( - self, - task_specification: Union[ - Circuit, Problem, OpenQASMProgram, AnalogHamiltonianSimulation, SerializableProgram - ], - shots: Optional[int] = None, - inputs: Optional[dict[str, float]] = None, - *args, - **kwargs, - ) -> Union[GateModelQuantumTaskResult, AnnealingQuantumTaskResult]: # pragma: no cover - """Wraps _run_interal for pickle dump""" - return self._run_internal(task_specification, shots, inputs=inputs, *args, **kwargs) - @singledispatchmethod - def _get_simulator(self, simulator: Union[str, BraketSimulator]) -> LocalSimulator: + def _get_simulator(self, simulator: Any) -> BraketSimulator: raise TypeError("Simulator must either be a string or a BraketSimulator instance") @_get_simulator.register @@ -261,66 +254,29 @@ def _(self, backend_impl: BraketSimulator): return backend_impl @singledispatchmethod - def _run_internal( + def _construct_payload( self, - task_specification: Union[ - Circuit, - Problem, - OpenQASMProgram, - AnalogHamiltonianSimulation, - AHSProgram, - SerializableProgram, - ], - shots: Optional[int] = None, - *args, - **kwargs, - ) -> Union[GateModelQuantumTaskResult, AnnealingQuantumTaskResult]: + task_specification: Any, + inputs: Optional[dict[str, float]], + shots: Optional[int], + ) -> Any: raise NotImplementedError(f"Unsupported task type {type(task_specification)}") - @_run_internal.register - def _( - self, - circuit: Circuit, - shots: Optional[int] = None, - inputs: Optional[dict[str, float]] = None, - *args, - **kwargs, - ): + @_construct_payload.register + def _(self, circuit: Circuit, inputs: Optional[dict[str, float]], shots: Optional[int]): simulator = self._delegate if DeviceActionType.OPENQASM in simulator.properties.action: validate_circuit_and_shots(circuit, shots) program = circuit.to_ir(ir_type=IRType.OPENQASM) program.inputs.update(inputs or {}) - results = simulator.run(program, shots, *args, **kwargs) - return GateModelQuantumTaskResult.from_object(results) + return program elif DeviceActionType.JAQCD in simulator.properties.action: validate_circuit_and_shots(circuit, shots) - program = circuit.to_ir(ir_type=IRType.JAQCD) - qubits = circuit.qubit_count - results = simulator.run(program, qubits, shots, *args, **kwargs) - return GateModelQuantumTaskResult.from_object(results) + return circuit.to_ir(ir_type=IRType.JAQCD) raise NotImplementedError(f"{type(simulator)} does not support qubit gate-based programs") - @_run_internal.register - def _(self, problem: Problem, shots: Optional[int] = None, *args, **kwargs): - simulator = self._delegate - if DeviceActionType.ANNEALING not in simulator.properties.action: - raise NotImplementedError( - f"{type(simulator)} does not support quantum annealing problems" - ) - ir = problem.to_ir() - results = simulator.run(ir, shots, *args, *kwargs) - return AnnealingQuantumTaskResult.from_object(results) - - @_run_internal.register - def _( - self, - program: OpenQASMProgram, - shots: Optional[int] = None, - inputs: Optional[dict[str, float]] = None, - *args, - **kwargs, - ): + @_construct_payload.register + def _(self, program: OpenQASMProgram, inputs: Optional[dict[str, float]], _shots): simulator = self._delegate if DeviceActionType.OPENQASM not in simulator.properties.action: raise NotImplementedError(f"{type(simulator)} does not support OpenQASM programs") @@ -331,54 +287,55 @@ def _( source=program.source, inputs=inputs_copy, ) + return program - results = simulator.run(program, shots, *args, **kwargs) - - if isinstance(results, GateModelQuantumTaskResult): - return results + @_construct_payload.register + def _(self, program: SerializableProgram, _inputs, _shots): + return OpenQASMProgram(source=program.to_ir(ir_type=IRType.OPENQASM)) - return GateModelQuantumTaskResult.from_object(results) - - @_run_internal.register - def _( - self, - program: SerializableProgram, - shots: Optional[int] = None, - inputs: Optional[dict[str, float]] = None, - *args, - **kwargs, - ): - program = OpenQASMProgram(source=program.to_ir(ir_type=IRType.OPENQASM)) - return self._run_internal(program, shots, inputs, *args, **kwargs) - - @_run_internal.register - def _( - self, - program: AnalogHamiltonianSimulation, - shots: Optional[int] = None, - *args, - **kwargs, - ): + @_construct_payload.register + def _(self, program: AnalogHamiltonianSimulation, _inputs, _shots): simulator = self._delegate if DeviceActionType.AHS not in simulator.properties.action: raise NotImplementedError( f"{type(simulator)} does not support analog Hamiltonian simulation programs" ) - results = simulator.run(program.to_ir(), shots, *args, **kwargs) - return AnalogHamiltonianSimulationQuantumTaskResult.from_object(results) + return program.to_ir() - @_run_internal.register - def _( - self, - program: AHSProgram, - shots: Optional[int] = None, - *args, - **kwargs, - ): + @_construct_payload.register + def _(self, program: AHSProgram, _inputs, _shots): simulator = self._delegate if DeviceActionType.AHS not in simulator.properties.action: raise NotImplementedError( f"{type(simulator)} does not support analog Hamiltonian simulation programs" ) - results = simulator.run(program, shots, *args, **kwargs) - return AnalogHamiltonianSimulationQuantumTaskResult.from_object(results) + return program + + @_construct_payload.register + def _(self, problem: Problem, _inputs, _shots): + simulator = self._delegate + if DeviceActionType.ANNEALING not in simulator.properties.action: + raise NotImplementedError( + f"{type(simulator)} does not support quantum annealing problems" + ) + return problem.to_ir() + + @singledispatchmethod + def _to_result_object(self, result: Any) -> Any: + raise NotImplementedError(f"Unsupported task result type {type(result)}") + + @_to_result_object.register + def _(self, result: GateModelQuantumTaskResult): + return result + + @_to_result_object.register + def _(self, result: GateModelTaskResult): + return GateModelQuantumTaskResult.from_object(result) + + @_to_result_object.register + def _(self, result: AnalogHamiltonianSimulationTaskResult): + return AnalogHamiltonianSimulationQuantumTaskResult.from_object(result) + + @_to_result_object.register + def _(self, result: AnnealingTaskResult): + return AnnealingQuantumTaskResult.from_object(result) diff --git a/test/unit_tests/braket/devices/test_local_simulator.py b/test/unit_tests/braket/devices/test_local_simulator.py index 216d161c7..451553f02 100644 --- a/test/unit_tests/braket/devices/test_local_simulator.py +++ b/test/unit_tests/braket/devices/test_local_simulator.py @@ -156,7 +156,12 @@ def properties(self) -> DeviceCapabilities: class DummyJaqcdSimulator(BraketSimulator): def run( - self, program: ir.jaqcd.Program, qubits: int, shots: Optional[int], *args, **kwargs + self, + program: ir.jaqcd.Program, + qubits: Optional[int] = None, + shots: Optional[int] = None, + *args, + **kwargs, ) -> dict[str, Any]: if not isinstance(program, ir.jaqcd.Program): raise TypeError("Not a Jaqcd program") @@ -520,7 +525,7 @@ def test_run_gate_model_inputs(): ), inputs={"theta": 2}, ), - 10, + shots=10, ) assert task.result() == GateModelQuantumTaskResult.from_object(GATE_MODEL_RESULT) @@ -543,7 +548,7 @@ def test_run_program_model_inputs(): task = sim.run(program, inputs=update_inputs, shots=10) assert program.inputs == inputs program.inputs.update(update_inputs) - dummy.run.assert_called_with(program, 10) + dummy.run.assert_called_with(program, shots=10) assert task.result() == GateModelQuantumTaskResult.from_object(GATE_MODEL_RESULT) @@ -552,7 +557,7 @@ def test_run_jaqcd_only(): sim = LocalSimulator(dummy) task = sim.run(Circuit().h(0).cnot(0, 1), 10) dummy.assert_shots(10) - dummy.assert_qubits(2) + dummy.assert_qubits(None) assert task.result() == GateModelQuantumTaskResult.from_object(GATE_MODEL_RESULT) @@ -713,7 +718,7 @@ def test_run_with_noise_model(mock_run, noise_model): mock_run.assert_called_with( Program(source=expected_circuit, inputs={}), - 4, + shots=4, ) @@ -753,7 +758,7 @@ def test_run_noisy_circuit_with_noise_model(mock_run, noise_model): mock_run.assert_called_with( Program(source=expected_circuit, inputs={}), - 4, + shots=4, ) assert w[-1].message.__str__() == expected_warning @@ -781,6 +786,6 @@ def test_run_openqasm_with_noise_model(mock_run, noise_model): mock_run.assert_called_with( Program(source=expected_circuit, inputs=None), - 4, + shots=4, ) assert w[-1].message.__str__() == expected_warning From 686aaf8c831c45e7bdecc9d5722dd2ef5151a3c0 Mon Sep 17 00:00:00 2001 From: Cody Wang Date: Fri, 28 Jun 2024 13:51:31 -0700 Subject: [PATCH 11/15] deprecation: Remove OQC (#1014) --- src/braket/devices/devices.py | 4 ++-- test/integ_tests/test_device_creation.py | 10 +++++----- test/integ_tests/test_measure.py | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/braket/devices/devices.py b/src/braket/devices/devices.py index fa2c6d025..86a32a142 100644 --- a/src/braket/devices/devices.py +++ b/src/braket/devices/devices.py @@ -37,7 +37,7 @@ class _IonQ(str, Enum): Forte1 = "arn:aws:braket:us-east-1::device/qpu/ionq/Forte-1" class _OQC(str, Enum): - Lucy = "arn:aws:braket:eu-west-2::device/qpu/oqc/Lucy" + _Lucy = "arn:aws:braket:eu-west-2::device/qpu/oqc/Lucy" class _QuEra(str, Enum): Aquila = "arn:aws:braket:us-east-1::device/qpu/quera/Aquila" @@ -58,7 +58,7 @@ class _Xanadu(str, Enum): # DWave = _DWave IonQ = _IonQ IQM = _IQM - OQC = _OQC + # OQC = _OQC QuEra = _QuEra Rigetti = _Rigetti # Xanadu = _Xanadu diff --git a/test/integ_tests/test_device_creation.py b/test/integ_tests/test_device_creation.py index 540c09f61..c7183c3e6 100644 --- a/test/integ_tests/test_device_creation.py +++ b/test/integ_tests/test_device_creation.py @@ -19,13 +19,13 @@ RIGETTI_ARN = "arn:aws:braket:us-west-1::device/qpu/rigetti/Aspen-M-3" IONQ_ARN = "arn:aws:braket:us-east-1::device/qpu/ionq/Harmony" +IQM_ARN = "arn:aws:braket:eu-north-1::device/qpu/iqm/Garnet" SIMULATOR_ARN = "arn:aws:braket:::device/quantum-simulator/amazon/sv1" -OQC_ARN = "arn:aws:braket:eu-west-2::device/qpu/oqc/Lucy" PULSE_ARN = "arn:aws:braket:us-west-1::device/qpu/rigetti/Aspen-M-3" @pytest.mark.parametrize( - "arn", [(RIGETTI_ARN), (IONQ_ARN), (OQC_ARN), (SIMULATOR_ARN), (PULSE_ARN)] + "arn", [(RIGETTI_ARN), (IONQ_ARN), (IQM_ARN), (SIMULATOR_ARN), (PULSE_ARN)] ) def test_device_creation(arn, created_braket_devices): device = created_braket_devices[arn] @@ -48,10 +48,10 @@ def test_device_across_regions(aws_session, created_braket_devices): # assert QPUs across different regions can be created using the same aws_session created_braket_devices[RIGETTI_ARN] created_braket_devices[IONQ_ARN] - created_braket_devices[OQC_ARN] + created_braket_devices[IQM_ARN] -@pytest.mark.parametrize("arn", [(RIGETTI_ARN), (IONQ_ARN), (OQC_ARN), (SIMULATOR_ARN)]) +@pytest.mark.parametrize("arn", [(RIGETTI_ARN), (IONQ_ARN), (IQM_ARN), (SIMULATOR_ARN)]) def test_get_devices_arn(arn): results = AwsDevice.get_devices(arns=[arn]) assert results[0].arn == arn @@ -77,7 +77,7 @@ def test_get_devices_others(): def test_get_devices_all(braket_devices): result_arns = [result.arn for result in braket_devices] - for arn in [RIGETTI_ARN, IONQ_ARN, SIMULATOR_ARN, OQC_ARN]: + for arn in [RIGETTI_ARN, IONQ_ARN, IQM_ARN, SIMULATOR_ARN]: assert arn in result_arns diff --git a/test/integ_tests/test_measure.py b/test/integ_tests/test_measure.py index b7fef275b..9c8fdc02c 100644 --- a/test/integ_tests/test_measure.py +++ b/test/integ_tests/test_measure.py @@ -25,7 +25,7 @@ IONQ_ARN = "arn:aws:braket:us-east-1::device/qpu/ionq/Harmony" SIMULATOR_ARN = "arn:aws:braket:::device/quantum-simulator/amazon/sv1" -OQC_ARN = "arn:aws:braket:eu-west-2::device/qpu/oqc/Lucy" +IQM_ARN = "arn:aws:braket:eu-north-1::device/qpu/iqm/Garnet" @pytest.mark.parametrize("arn", [(IONQ_ARN), (SIMULATOR_ARN)]) @@ -53,7 +53,7 @@ def test_measure_on_local_sim(sim): assert result.measured_qubits == [0, 1] -@pytest.mark.parametrize("arn", [(OQC_ARN)]) +@pytest.mark.parametrize("arn", [(IQM_ARN)]) def test_measure_on_supported_devices(arn): device = AwsDevice(arn) if not device.is_available: From 1e4a76f0d502ac8fdbbeaf9d786ad3d4402b7b63 Mon Sep 17 00:00:00 2001 From: ci Date: Fri, 28 Jun 2024 21:49:49 +0000 Subject: [PATCH 12/15] prepare release v1.83.0 --- CHANGELOG.md | 14 ++++++++++++++ src/braket/_sdk/_version.py | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f6716703f..e50f15a39 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,19 @@ # Changelog +## v1.83.0 (2024-06-28) + +### Deprecations and Removals + + * Remove OQC + +### Features + + * Use `run_multiple` for local batches + +### Documentation Changes + + * update PR title instructions + ## v1.82.0 (2024-06-27) ### Features diff --git a/src/braket/_sdk/_version.py b/src/braket/_sdk/_version.py index 4d28af096..ed31be55f 100644 --- a/src/braket/_sdk/_version.py +++ b/src/braket/_sdk/_version.py @@ -15,4 +15,4 @@ Version number (major.minor.patch[-label]) """ -__version__ = "1.82.1.dev0" +__version__ = "1.83.0" From e72299b7fa261be5bb62661ec68b04dd368d1804 Mon Sep 17 00:00:00 2001 From: ci Date: Fri, 28 Jun 2024 21:49:49 +0000 Subject: [PATCH 13/15] update development version to v1.83.1.dev0 --- src/braket/_sdk/_version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/braket/_sdk/_version.py b/src/braket/_sdk/_version.py index ed31be55f..f91167665 100644 --- a/src/braket/_sdk/_version.py +++ b/src/braket/_sdk/_version.py @@ -15,4 +15,4 @@ Version number (major.minor.patch[-label]) """ -__version__ = "1.83.0" +__version__ = "1.83.1.dev0" From f42f3221c8cd184f3b3b0935371bd0442efebd79 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Jul 2024 15:02:15 -0400 Subject: [PATCH 14/15] infra: bump actions/checkout from 4.1.5 to 4.1.7 (#1015) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/check-format.yml | 2 +- .github/workflows/dependent-tests.yml | 2 +- .github/workflows/publish-to-pypi.yml | 2 +- .github/workflows/python-package.yml | 2 +- .github/workflows/twine-check.yml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/check-format.yml b/.github/workflows/check-format.yml index 942e35cc9..e047484ad 100644 --- a/.github/workflows/check-format.yml +++ b/.github/workflows/check-format.yml @@ -16,7 +16,7 @@ jobs: check-code-format: runs-on: ubuntu-latest steps: - - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5 + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: Set up Python uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0 with: diff --git a/.github/workflows/dependent-tests.yml b/.github/workflows/dependent-tests.yml index cfb58c2f8..ab2656bc0 100644 --- a/.github/workflows/dependent-tests.yml +++ b/.github/workflows/dependent-tests.yml @@ -21,7 +21,7 @@ jobs: - amazon-braket-pennylane-plugin-python steps: - - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5 + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0 with: diff --git a/.github/workflows/publish-to-pypi.yml b/.github/workflows/publish-to-pypi.yml index 129f2f9f7..942974db7 100644 --- a/.github/workflows/publish-to-pypi.yml +++ b/.github/workflows/publish-to-pypi.yml @@ -12,7 +12,7 @@ jobs: name: Build and publish distribution to PyPi runs-on: ubuntu-latest steps: - - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5 + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: Set up Python uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0 with: diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 2f6b9992b..8ce80816f 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -24,7 +24,7 @@ jobs: python-version: ["3.9", "3.10", "3.11"] steps: - - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5 + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0 with: diff --git a/.github/workflows/twine-check.yml b/.github/workflows/twine-check.yml index b3bd97833..3b439db6d 100644 --- a/.github/workflows/twine-check.yml +++ b/.github/workflows/twine-check.yml @@ -14,7 +14,7 @@ jobs: name: Check long description runs-on: ubuntu-latest steps: - - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5 + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: Set up Python uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0 with: From bbdbfa64cd63ae1b035a48c3eaa6485f43309c60 Mon Sep 17 00:00:00 2001 From: Cody Wang Date: Tue, 2 Jul 2024 13:28:51 -0700 Subject: [PATCH 15/15] test: Add Garnet to tracker integ test (#1016) --- test/integ_tests/test_cost_tracking.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integ_tests/test_cost_tracking.py b/test/integ_tests/test_cost_tracking.py index 0c06f297a..f493c9779 100644 --- a/test/integ_tests/test_cost_tracking.py +++ b/test/integ_tests/test_cost_tracking.py @@ -28,7 +28,7 @@ "qpu", [ "arn:aws:braket:us-east-1::device/qpu/ionq/Harmony", - "arn:aws:braket:eu-west-2::device/qpu/oqc/Lucy", + "arn:aws:braket:eu-north-1::device/qpu/iqm/Garnet", "arn:aws:braket:us-west-1::device/qpu/rigetti/Aspen-M-3", ], )