From d9c9ede87933d56a63134feda1566eb5b100e0b2 Mon Sep 17 00:00:00 2001 From: Nagji Date: Thu, 20 Jun 2024 14:12:14 -0700 Subject: [PATCH 01/10] fix: Add classical targets option to add_measure instruction in BraketProgramContext --- src/braket/circuits/braket_program_context.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/braket/circuits/braket_program_context.py b/src/braket/circuits/braket_program_context.py index 4371637d3..29f76bdd3 100644 --- a/src/braket/circuits/braket_program_context.py +++ b/src/braket/circuits/braket_program_context.py @@ -12,6 +12,7 @@ # language governing permissions and limitations under the License. from typing import Optional, Union +from collections.abc import Iterable import numpy as np from sympy import Expr, Number @@ -161,13 +162,14 @@ 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: Iterable[int] = None) -> None: """Add a measure instruction to the circuit Args: target (tuple[int]): the target qubits to be measured. """ - 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: From e2c4b558420e52b25641d5937f559895145e196b Mon Sep 17 00:00:00 2001 From: Nagji Date: Mon, 24 Jun 2024 13:44:38 -0700 Subject: [PATCH 02/10] fix: Update add_instruction to update circuit _measurement_targets at the instruction level instead of only if add_measure is called. --- src/braket/circuits/braket_program_context.py | 4 ---- src/braket/circuits/circuit.py | 14 +++++++---- .../braket/circuits/test_circuit.py | 23 +++++++++++++++++++ 3 files changed, 32 insertions(+), 9 deletions(-) diff --git a/src/braket/circuits/braket_program_context.py b/src/braket/circuits/braket_program_context.py index 29f76bdd3..f3c75cd4f 100644 --- a/src/braket/circuits/braket_program_context.py +++ b/src/braket/circuits/braket_program_context.py @@ -172,7 +172,3 @@ def add_measure(self, target: tuple[int], classical_targets: Iterable[int] = Non 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..ff846c237 100644 --- a/src/braket/circuits/circuit.py +++ b/src/braket/circuits/circuit.py @@ -503,7 +503,14 @@ 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): + if self._measure_targets: + self._measure_targets.append(target or instruction.target[0]) + else: + self._measure_targets = [target or instruction.target[0]] + if not target_mapping and not target: # Nothing has been supplied, add instruction instructions_to_add = [instruction] @@ -710,10 +717,7 @@ 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: """ diff --git a/test/unit_tests/braket/circuits/test_circuit.py b/test/unit_tests/braket/circuits/test_circuit.py index 71eecd1f1..755fc77fa 100644 --- a/test/unit_tests/braket/circuits/test_circuit.py +++ b/test/unit_tests/braket/circuits/test_circuit.py @@ -890,6 +890,29 @@ def test_from_ir_round_trip_transformation(): assert Circuit.from_ir(ir) == Circuit.from_ir(circuit.to_ir("OPENQASM")) assert circuit.to_ir("OPENQASM") == Circuit.from_ir(ir).to_ir("OPENQASM") +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") def test_add_with_instruction_with_default(cnot_instr): circ = Circuit().add(cnot_instr) From a55edb24e7c515f3256e83dec4054d8e92898988 Mon Sep 17 00:00:00 2001 From: Nagji Date: Tue, 25 Jun 2024 17:04:31 -0700 Subject: [PATCH 03/10] change: Target default simulator branch with classical register indices implementation --- setup.py | 2 +- tox.ini | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index 43d2c52ad..3845fd479 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 @ git+https://github.com/Altanali/amazon-braket-default-simulator-python.git@main", "oqpy~=0.3.5", "backoff", "boltons", diff --git a/tox.ini b/tox.ini index 95c862106..39ef86dd5 100644 --- a/tox.ini +++ b/tox.ini @@ -130,4 +130,4 @@ commands = deps = # If you need to test on a certain branch, add @ after .git git+https://github.com/amazon-braket/amazon-braket-schemas-python.git - git+https://github.com/amazon-braket/amazon-braket-default-simulator-python.git + git+https://github.com/Altanali/amazon-braket-default-simulator-python.git@main From e39941d30ade90d9719c8ea86654e029e345f517 Mon Sep 17 00:00:00 2001 From: Nagji Date: Tue, 25 Jun 2024 17:32:45 -0700 Subject: [PATCH 04/10] fix: Run linter and fix formatting/complexity --- setup.py | 3 ++- src/braket/circuits/braket_program_context.py | 9 +++++++-- src/braket/circuits/circuit.py | 13 +++++-------- .../unit_tests/braket/circuits/test_circuit.py | 18 ++++++++++++------ 4 files changed, 26 insertions(+), 17 deletions(-) diff --git a/setup.py b/setup.py index 3845fd479..ca5b0f943 100644 --- a/setup.py +++ b/setup.py @@ -28,7 +28,8 @@ package_dir={"": "src"}, install_requires=[ "amazon-braket-schemas>=1.21.3", - "amazon-braket-default-simulator @ git+https://github.com/Altanali/amazon-braket-default-simulator-python.git@main", + "amazon-braket-default-simulator @ \ + git+https://github.com/Altanali/amazon-braket-default-simulator-python.git@main", "oqpy~=0.3.5", "backoff", "boltons", diff --git a/src/braket/circuits/braket_program_context.py b/src/braket/circuits/braket_program_context.py index f3c75cd4f..37ddaf012 100644 --- a/src/braket/circuits/braket_program_context.py +++ b/src/braket/circuits/braket_program_context.py @@ -11,8 +11,8 @@ # ANY KIND, either express or implied. See the License for the specific # language governing permissions and limitations under the License. -from typing import Optional, Union from collections.abc import Iterable +from typing import Optional, Union import numpy as np from sympy import Expr, Number @@ -162,11 +162,16 @@ def handle_parameter_value( return FreeParameterExpression(evaluated_value) return value - def add_measure(self, target: tuple[int], classical_targets: Iterable[int] = None) -> None: + def add_measure( + self, target: tuple[int], classical_targets: Iterable[int] | None = None + ) -> None: """Add a measure instruction to the circuit Args: target (tuple[int]): the target qubits to be measured. + + classical_targets (Iterable[int] | None): the classical registers + to use in the qubit measurement. """ for iter, qubit in enumerate(target): index = classical_targets[iter] if classical_targets else iter diff --git a/src/braket/circuits/circuit.py b/src/braket/circuits/circuit.py index ff846c237..9ce7df7f8 100644 --- a/src/braket/circuits/circuit.py +++ b/src/braket/circuits/circuit.py @@ -503,14 +503,12 @@ 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 + + # Update measure targets if instruction is a measurement if isinstance(instruction.operator, Measure): - if self._measure_targets: - self._measure_targets.append(target or instruction.target[0]) - else: - self._measure_targets = [target or instruction.target[0]] - + 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] @@ -718,7 +716,6 @@ def _add_measure(self, target_qubits: QubitSetInput) -> None: ) ) - def measure(self, target_qubits: QubitSetInput) -> Circuit: """ Add a `measure` operator to `self` ensuring only the target qubits are measured. diff --git a/test/unit_tests/braket/circuits/test_circuit.py b/test/unit_tests/braket/circuits/test_circuit.py index 755fc77fa..a126768ee 100644 --- a/test/unit_tests/braket/circuits/test_circuit.py +++ b/test/unit_tests/braket/circuits/test_circuit.py @@ -890,11 +890,16 @@ def test_from_ir_round_trip_transformation(): assert Circuit.from_ir(ir) == Circuit.from_ir(circuit.to_ir("OPENQASM")) assert circuit.to_ir("OPENQASM") == Circuit.from_ir(ir).to_ir("OPENQASM") + 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)) + 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( [ @@ -904,8 +909,8 @@ def test_from_ir_round_trip_transformation_with_targeted_measurements(): "h q[0];", "cnot q[0], q[1];", "b[2] = measure q[1];", - "b[1] = measure q[2];", - "b[0] = measure q[0];" + "b[1] = measure q[2];", + "b[0] = measure q[0];", ] ), inputs={}, @@ -914,6 +919,7 @@ def test_from_ir_round_trip_transformation_with_targeted_measurements(): assert Circuit.from_ir(ir) == Circuit.from_ir(circuit.to_ir("OPENQASM")) assert circuit.to_ir("OPENQASM") == Circuit.from_ir(ir).to_ir("OPENQASM") + def test_add_with_instruction_with_default(cnot_instr): circ = Circuit().add(cnot_instr) assert circ == Circuit().add_instruction(cnot_instr) From 7b3ebf3ffab8e442e0c87d60c003d46cc664b227 Mon Sep 17 00:00:00 2001 From: Nagji Date: Wed, 26 Jun 2024 12:02:05 -0700 Subject: [PATCH 05/10] fix: Revert default simulator versions and dependent round_trip tests --- setup.py | 3 +- .../braket/circuits/test_circuit.py | 29 ------------------- tox.ini | 2 +- 3 files changed, 2 insertions(+), 32 deletions(-) diff --git a/setup.py b/setup.py index ca5b0f943..43d2c52ad 100644 --- a/setup.py +++ b/setup.py @@ -28,8 +28,7 @@ package_dir={"": "src"}, install_requires=[ "amazon-braket-schemas>=1.21.3", - "amazon-braket-default-simulator @ \ - git+https://github.com/Altanali/amazon-braket-default-simulator-python.git@main", + "amazon-braket-default-simulator>=1.21.4", "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 a126768ee..71eecd1f1 100644 --- a/test/unit_tests/braket/circuits/test_circuit.py +++ b/test/unit_tests/braket/circuits/test_circuit.py @@ -891,35 +891,6 @@ def test_from_ir_round_trip_transformation(): assert circuit.to_ir("OPENQASM") == Circuit.from_ir(ir).to_ir("OPENQASM") -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") - - def test_add_with_instruction_with_default(cnot_instr): circ = Circuit().add(cnot_instr) assert circ == Circuit().add_instruction(cnot_instr) diff --git a/tox.ini b/tox.ini index 39ef86dd5..95c862106 100644 --- a/tox.ini +++ b/tox.ini @@ -130,4 +130,4 @@ commands = deps = # If you need to test on a certain branch, add @ after .git git+https://github.com/amazon-braket/amazon-braket-schemas-python.git - git+https://github.com/Altanali/amazon-braket-default-simulator-python.git@main + git+https://github.com/amazon-braket/amazon-braket-default-simulator-python.git From b5828ad64ada29f8547eb3f0015a93cfeeb98c47 Mon Sep 17 00:00:00 2001 From: Cody Wang Date: Wed, 26 Jun 2024 12:23:43 -0700 Subject: [PATCH 06/10] Update src/braket/circuits/braket_program_context.py --- src/braket/circuits/braket_program_context.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/braket/circuits/braket_program_context.py b/src/braket/circuits/braket_program_context.py index 37ddaf012..499d55543 100644 --- a/src/braket/circuits/braket_program_context.py +++ b/src/braket/circuits/braket_program_context.py @@ -163,14 +163,14 @@ def handle_parameter_value( return value def add_measure( - self, target: tuple[int], classical_targets: Iterable[int] | None = None + self, target: tuple[int], classical_targets: Union[Iterable[int], None] = None ) -> None: """Add a measure instruction to the circuit Args: target (tuple[int]): the target qubits to be measured. - classical_targets (Iterable[int] | None): the classical registers + classical_targets (Union[Iterable[int], None]): the classical registers to use in the qubit measurement. """ for iter, qubit in enumerate(target): From 6b0ad924b87696930fcef663f1a5c9eb26ecb706 Mon Sep 17 00:00:00 2001 From: Cody Wang Date: Wed, 26 Jun 2024 12:26:32 -0700 Subject: [PATCH 07/10] Update src/braket/circuits/braket_program_context.py --- src/braket/circuits/braket_program_context.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/braket/circuits/braket_program_context.py b/src/braket/circuits/braket_program_context.py index 499d55543..7b751f89c 100644 --- a/src/braket/circuits/braket_program_context.py +++ b/src/braket/circuits/braket_program_context.py @@ -163,14 +163,14 @@ def handle_parameter_value( return value def add_measure( - self, target: tuple[int], classical_targets: Union[Iterable[int], None] = None + 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 (Union[Iterable[int], None]): the classical registers + classical_targets (Optional[Iterable[int]]): the classical registers to use in the qubit measurement. """ for iter, qubit in enumerate(target): From ece64a42a0333cea307d8048cb61d162e1202ba2 Mon Sep 17 00:00:00 2001 From: Cody Wang Date: Wed, 26 Jun 2024 12:26:55 -0700 Subject: [PATCH 08/10] Update src/braket/circuits/braket_program_context.py --- src/braket/circuits/braket_program_context.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/braket/circuits/braket_program_context.py b/src/braket/circuits/braket_program_context.py index 7b751f89c..558692510 100644 --- a/src/braket/circuits/braket_program_context.py +++ b/src/braket/circuits/braket_program_context.py @@ -169,7 +169,6 @@ def add_measure( Args: target (tuple[int]): the target qubits to be measured. - classical_targets (Optional[Iterable[int]]): the classical registers to use in the qubit measurement. """ From ae3a0e3d39a151ff1dab7d787352c702f5ec4d49 Mon Sep 17 00:00:00 2001 From: Nagji Date: Wed, 26 Jun 2024 16:25:04 -0700 Subject: [PATCH 09/10] fix: Add round_trip test for classical target tracking during measurement --- setup.py | 2 +- .../braket/circuits/test_circuit.py | 28 +++++++++++++++++++ 2 files changed, 29 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..b6bf39562 100644 --- a/test/unit_tests/braket/circuits/test_circuit.py +++ b/test/unit_tests/braket/circuits/test_circuit.py @@ -3610,3 +3610,31 @@ 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") \ No newline at end of file From 8756960c66682e874accd72b3509d573cb91b8a2 Mon Sep 17 00:00:00 2001 From: Nagji Date: Wed, 26 Jun 2024 16:36:02 -0700 Subject: [PATCH 10/10] change: Run Linter --- test/unit_tests/braket/circuits/test_circuit.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/unit_tests/braket/circuits/test_circuit.py b/test/unit_tests/braket/circuits/test_circuit.py index b6bf39562..897828b27 100644 --- a/test/unit_tests/braket/circuits/test_circuit.py +++ b/test/unit_tests/braket/circuits/test_circuit.py @@ -3611,6 +3611,7 @@ def test_circuit_with_global_phase(): ] ) + def test_from_ir_round_trip_transformation_with_targeted_measurements(): circuit = ( Circuit() @@ -3637,4 +3638,4 @@ def test_from_ir_round_trip_transformation_with_targeted_measurements(): ) assert Circuit.from_ir(ir) == Circuit.from_ir(circuit.to_ir("OPENQASM")) - assert circuit.to_ir("OPENQASM") == Circuit.from_ir(ir).to_ir("OPENQASM") \ No newline at end of file + assert circuit.to_ir("OPENQASM") == Circuit.from_ir(ir).to_ir("OPENQASM")