-
Notifications
You must be signed in to change notification settings - Fork 118
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feature: Add delay and barrier for circuits #993
Merged
rmshaffer
merged 32 commits into
amazon-braket:feature/delay-barrier-instructions
from
Manvi-Agrawal:hack/delay-barrier
Jun 17, 2024
Merged
Changes from 7 commits
Commits
Show all changes
32 commits
Select commit
Hold shift + click to select a range
a6faeac
Feature: Add delay and barrier for circuits
Manvi-Agrawal 8c05927
doc: Add documentation for delay and barriers
Manvi-Agrawal 704439f
fix: update hash function
Manvi-Agrawal fbfc53a
rename
Manvi-Agrawal 0ffcdac
fix: whitespace fix
Manvi-Agrawal aa2d365
Apply suggestions from code review
Manvi-Agrawal 40069fa
Address PR comments
Manvi-Agrawal f29f49f
Update test/unit_tests/braket/circuits/test_gates.py
Manvi-Agrawal 9358d25
fix: update failing tests
Manvi-Agrawal 2bba6ba
Change duration
Manvi-Agrawal 5f15e12
change: add unit tests as per PR feedback
Manvi-Agrawal ff8295f
Apply suggestions from code review
Manvi-Agrawal 55018e9
Addressing pr feedback
Manvi-Agrawal 24946be
Merge branch 'hack/delay-barrier' of https://github.com/Manvi-Agrawal…
Manvi-Agrawal ef44828
pr feedback: new function
Manvi-Agrawal d8ece2e
fix: update int as param in delay and barrier
Manvi-Agrawal d7887e5
fix: duration accepts FreeParameter expression
Manvi-Agrawal 6689001
fix: fix lint errors
Manvi-Agrawal 8538e1e
feat: Support SI units, write ascii tests, etc
Manvi-Agrawal c44e576
fix: lint errors
Manvi-Agrawal 57a42c1
change: Add tests for IR generation of FreeParameter delay.
Manvi-Agrawal 2752a5e
add tests for ASCII and circuit visualization
Manvi-Agrawal eb5af0b
change: add tests for DurationGate
Manvi-Agrawal a5745a4
lint fix
Manvi-Agrawal 112cc3b
chore: Add more tests
Manvi-Agrawal 79945c3
fix: failing test
Manvi-Agrawal 5f097e0
revert
Manvi-Agrawal 2adb6f6
Rearrande tests and minor edit
Manvi-Agrawal ce359f5
Pr feedback and cleanup
Manvi-Agrawal a07eadd
Merge branch 'main' into hack/delay-barrier
rmshaffer 43c8156
Merge branch 'main' into hack/delay-barrier
rmshaffer ebc96f0
Merge branch 'main' into hack/delay-barrier
rmshaffer File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,6 +15,7 @@ | |
|
||
import numpy as np | ||
import pytest | ||
from pydantic.v1 import BaseModel, confloat | ||
|
||
import braket.ir.jaqcd as ir | ||
from braket.circuits import Circuit, FreeParameter, Gate, Instruction, QubitSet | ||
|
@@ -39,6 +40,14 @@ class NoTarget: | |
pass | ||
|
||
|
||
class Duration(BaseModel): | ||
duration: confloat(ge=0) | ||
Manvi-Agrawal marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
|
||
class NoMatrixGeneration: | ||
pass | ||
|
||
|
||
class DoubleAngle: | ||
pass | ||
|
||
|
@@ -68,6 +77,8 @@ class SingleNegControlModifier: | |
(Gate.Ry, "ry", ir.Ry, [SingleTarget, Angle], {}), | ||
(Gate.Rz, "rz", ir.Rz, [SingleTarget, Angle], {}), | ||
(Gate.U, "u", None, [SingleTarget, TripleAngle], {}), | ||
(Gate.Barrier, "barrier", None, [MultiTarget, NoMatrixGeneration], {}), | ||
(Gate.Delay, "delay", None, [MultiTarget, Duration, NoMatrixGeneration], {}), | ||
(Gate.CNot, "cnot", ir.CNot, [SingleTarget, SingleControl], {}), | ||
(Gate.CV, "cv", ir.CV, [SingleTarget, SingleControl], {}), | ||
(Gate.CCNot, "ccnot", ir.CCNot, [SingleTarget, DoubleControl], {}), | ||
|
@@ -170,6 +181,15 @@ def no_target_valid_input(**kwargs): | |
return {} | ||
|
||
|
||
def no_matrix_valid_input(**kwargs): | ||
qubit_count = 1 | ||
Manvi-Agrawal marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
if kwargs.get("target", None) is not None: | ||
qubit_count = len(kwargs.get("target")) | ||
|
||
return {"qubit_count": qubit_count} | ||
|
||
|
||
def single_target_valid_input(**kwargs): | ||
return {"target": 2} | ||
|
||
|
@@ -194,6 +214,10 @@ def triple_angle_valid_input(**kwargs): | |
return {"angle_1": 0.123, "angle_2": 4.567, "angle_3": 8.910} | ||
|
||
|
||
def duration_valid_input(**kwargs): | ||
return {"duration": 30.0} | ||
Manvi-Agrawal marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
|
||
def single_control_valid_input(**kwargs): | ||
return {"control": 0} | ||
|
||
|
@@ -225,6 +249,7 @@ def two_dimensional_matrix_valid_input(**kwargs): | |
|
||
valid_ir_switcher = { | ||
"NoTarget": no_target_valid_input, | ||
"NoMatrix": no_target_valid_input, | ||
Manvi-Agrawal marked this conversation as resolved.
Show resolved
Hide resolved
|
||
"SingleTarget": single_target_valid_input, | ||
"DoubleTarget": double_target_valid_ir_input, | ||
"Angle": angle_valid_input, | ||
|
@@ -235,6 +260,7 @@ def two_dimensional_matrix_valid_input(**kwargs): | |
"DoubleControl": double_control_valid_ir_input, | ||
"MultiTarget": multi_target_valid_input, | ||
"TwoDimensionalMatrix": two_dimensional_matrix_valid_ir_input, | ||
"Duration": duration_valid_input, | ||
} | ||
|
||
valid_subroutine_switcher = dict( | ||
|
@@ -284,7 +310,14 @@ def create_valid_target_input(irsubclasses): | |
control_state = list(single_neg_control_valid_input()["control_state"]) | ||
elif subclass == DoubleControl: | ||
qubit_set = list(double_control_valid_ir_input().values()) + qubit_set | ||
elif subclass not in (Angle, TwoDimensionalMatrix, DoubleAngle, TripleAngle): | ||
elif subclass not in ( | ||
Angle, | ||
Duration, | ||
NoMatrixGeneration, | ||
TwoDimensionalMatrix, | ||
DoubleAngle, | ||
TripleAngle, | ||
): | ||
raise ValueError("Invalid subclass") | ||
input = {"target": QubitSet(qubit_set)} | ||
input["control"] = QubitSet(control_qubit_set) | ||
|
@@ -302,6 +335,10 @@ def create_valid_gate_class_input(irsubclasses, **kwargs): | |
input.update(triple_angle_valid_input()) | ||
if TwoDimensionalMatrix in irsubclasses: | ||
input.update(two_dimensional_matrix_valid_input(**kwargs)) | ||
if NoMatrixGeneration in irsubclasses: | ||
input.update(no_matrix_valid_input(**kwargs)) | ||
if Duration in irsubclasses: | ||
input.update(duration_valid_input(**kwargs)) | ||
return input | ||
|
||
|
||
|
@@ -326,12 +363,14 @@ def calculate_qubit_count(irsubclasses): | |
qubit_count += 3 | ||
elif subclass not in ( | ||
NoTarget, | ||
NoMatrixGeneration, | ||
Angle, | ||
Duration, | ||
TwoDimensionalMatrix, | ||
DoubleAngle, | ||
TripleAngle, | ||
): | ||
raise ValueError("Invalid subclass") | ||
raise ValueError(f"Invalid subclass: {subclass}") | ||
Manvi-Agrawal marked this conversation as resolved.
Show resolved
Hide resolved
|
||
return qubit_count | ||
|
||
|
||
|
@@ -408,6 +447,30 @@ def test_ir_gate_level(testclass, subroutine_name, irclass, irsubclasses, kwargs | |
OpenQASMSerializationProperties(qubit_reference_type=QubitReferenceType.PHYSICAL), | ||
"h $4;", | ||
), | ||
( | ||
Gate.Barrier(3), | ||
[3, 4, 5], | ||
Manvi-Agrawal marked this conversation as resolved.
Show resolved
Hide resolved
|
||
OpenQASMSerializationProperties(qubit_reference_type=QubitReferenceType.VIRTUAL), | ||
"barrier q[3], q[4], q[5];", | ||
), | ||
( | ||
Gate.Barrier(3), | ||
[3, 4, 5], | ||
OpenQASMSerializationProperties(qubit_reference_type=QubitReferenceType.PHYSICAL), | ||
"barrier $3, $4, $5;", | ||
), | ||
( | ||
Gate.Delay(qubit_count=3, duration=30), | ||
[3, 4, 5], | ||
OpenQASMSerializationProperties(qubit_reference_type=QubitReferenceType.VIRTUAL), | ||
"delay[30 s] q[3], q[4], q[5];", | ||
), | ||
( | ||
Gate.Delay(qubit_count=3, duration=30), | ||
[3, 4, 5], | ||
OpenQASMSerializationProperties(qubit_reference_type=QubitReferenceType.PHYSICAL), | ||
"delay[30 s] $3, $4, $5;", | ||
Manvi-Agrawal marked this conversation as resolved.
Show resolved
Hide resolved
|
||
), | ||
( | ||
Gate.Ry(angle=0.17), | ||
[4], | ||
|
@@ -889,12 +952,10 @@ def test_ir_gate_level(testclass, subroutine_name, irclass, irsubclasses, kwargs | |
], | ||
) | ||
def test_gate_to_ir_openqasm(gate, target, serialization_properties, expected_ir): | ||
assert ( | ||
gate.to_ir( | ||
target, ir_type=IRType.OPENQASM, serialization_properties=serialization_properties | ||
) | ||
== expected_ir | ||
actual_ir = gate.to_ir( | ||
target, ir_type=IRType.OPENQASM, serialization_properties=serialization_properties | ||
) | ||
assert actual_ir == expected_ir | ||
|
||
|
||
@pytest.mark.parametrize("testclass,subroutine_name,irclass,irsubclasses,kwargs", testdata) | ||
|
@@ -979,19 +1040,21 @@ def test_angle_gphase_is_none(): | |
|
||
@pytest.mark.parametrize("testclass,subroutine_name,irclass,irsubclasses,kwargs", testdata) | ||
def test_gate_adjoint_expansion_correct(testclass, subroutine_name, irclass, irsubclasses, kwargs): | ||
gate = testclass(**create_valid_gate_class_input(irsubclasses, **kwargs)) | ||
matrices = [elem.to_matrix() for elem in gate.adjoint()] | ||
matrices.append(gate.to_matrix()) | ||
identity = np.eye(2**gate.qubit_count) | ||
assert np.allclose(functools.reduce(lambda a, b: a @ b, matrices), identity) | ||
if NoMatrixGeneration not in irsubclasses: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This makes me think that we need to check if it works (or at least returns an understandable error message) with simulators. |
||
gate = testclass(**create_valid_gate_class_input(irsubclasses, **kwargs)) | ||
matrices = [elem.to_matrix() for elem in gate.adjoint()] | ||
matrices.append(gate.to_matrix()) | ||
identity = np.eye(2**gate.qubit_count) | ||
assert np.allclose(functools.reduce(lambda a, b: a @ b, matrices), identity) | ||
|
||
|
||
@pytest.mark.parametrize("testclass,subroutine_name,irclass,irsubclasses,kwargs", testdata) | ||
def test_gate_to_matrix(testclass, subroutine_name, irclass, irsubclasses, kwargs): | ||
gate1 = testclass(**create_valid_gate_class_input(irsubclasses, **kwargs)) | ||
gate2 = testclass(**create_valid_gate_class_input(irsubclasses, **kwargs)) | ||
assert isinstance(gate1.to_matrix(), np.ndarray) | ||
assert gate1.matrix_equivalence(gate2) | ||
if NoMatrixGeneration not in irsubclasses: | ||
gate1 = testclass(**create_valid_gate_class_input(irsubclasses, **kwargs)) | ||
gate2 = testclass(**create_valid_gate_class_input(irsubclasses, **kwargs)) | ||
assert isinstance(gate1.to_matrix(), np.ndarray) | ||
assert gate1.matrix_equivalence(gate2) | ||
|
||
|
||
@pytest.mark.parametrize("testclass,subroutine_name,irclass,irsubclasses,kwargs", testdata) | ||
|
@@ -1042,6 +1105,7 @@ def test_large_unitary(): | |
def test_bind_values(gate): | ||
double_angled = gate.__name__ in ["PRx"] | ||
triple_angled = gate.__name__ in ("MS", "U") | ||
duration = gate.__name__ in ("Delay") | ||
num_params = 1 | ||
if triple_angled: | ||
num_params = 3 | ||
|
@@ -1060,6 +1124,8 @@ def test_bind_values(gate): | |
elif double_angled: | ||
for angle in new_gate.angle_1, new_gate.angle_2: | ||
assert isinstance(angle, float) | ||
elif duration: | ||
Manvi-Agrawal marked this conversation as resolved.
Show resolved
Hide resolved
|
||
assert isinstance(new_gate.duration, float) | ||
else: | ||
assert isinstance(new_gate.angle, float) | ||
|
||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sold yet on whether it should be a
Gate
or something else like aCompilerDirective
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jcjaskula-aws , @rmshaffer , did you get a chance to brainstorm if its okay to proceed with Barrier as a Gate?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with @jcjaskula-aws - I think
CompilerDirective
makes the most sense here, since these are not instructions which directly affect the state of the qubits.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Manvi-Agrawal were you able to try converting this to be a
CompilerDirective
instead of aGate
? Please let us know if you hit any issues with this.