Skip to content
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

feat: add U and GPhase gates #799

Merged
merged 55 commits into from
Dec 20, 2023
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
d784d88
Add U gate
jcjaskula-aws Nov 14, 2023
9633a2a
modification according to feedback
jcjaskula-aws Nov 14, 2023
e68e78c
fix linters
jcjaskula-aws Nov 14, 2023
0c2c9e8
clean commented code
jcjaskula-aws Nov 14, 2023
c3044cb
first version of gphase
jcjaskula-aws Nov 15, 2023
d6d6886
handle drawing and control global phase
jcjaskula-aws Nov 15, 2023
388367c
Adding a global phase attribute
jcjaskula-aws Nov 17, 2023
7a52eb8
add global phase to circuit unitary
jcjaskula-aws Nov 18, 2023
d8917f3
Merge branch 'main' into jcjaskula-aws/add_u_gate
jcjaskula-aws Nov 19, 2023
f35cc38
first draft tests to check coverage
jcjaskula-aws Nov 20, 2023
fa4cb3a
add more tests
jcjaskula-aws Nov 20, 2023
5ddf96e
add test with parametric global phase
jcjaskula-aws Nov 20, 2023
3c0d766
add test for neg control qubit printing
jcjaskula-aws Nov 20, 2023
9f8a547
clean up
jcjaskula-aws Nov 20, 2023
76989f7
simplify ctrl-gphase transform
jcjaskula-aws Nov 20, 2023
f1204d0
feat: add str, repr and getitem to BasisState
ajberdy Nov 21, 2023
f5d0511
add repr coverage
ajberdy Nov 21, 2023
f68b084
add index
jcjaskula-aws Nov 21, 2023
5c56724
add pop
jcjaskula-aws Nov 21, 2023
70844ee
Merge branch 'basis-state-slice' into jcjaskula-aws/add_u_gate
jcjaskula-aws Nov 21, 2023
dabb790
fix phase target qubit
jcjaskula-aws Nov 21, 2023
31a60f8
fix typing
jcjaskula-aws Nov 21, 2023
0b02f14
add index and pop tests
jcjaskula-aws Nov 21, 2023
0a7985e
fix code coverage
jcjaskula-aws Nov 21, 2023
c75f331
move unitary matrices
jcjaskula-aws Nov 21, 2023
df1b1a9
use a subindex in MomentKey
jcjaskula-aws Nov 23, 2023
daa9cd9
print global phase integration
jcjaskula-aws Nov 24, 2023
9e5f7dc
fix docstrings
jcjaskula-aws Nov 24, 2023
aa46064
fix circuits zero total global phase
jcjaskula-aws Nov 24, 2023
590d9c8
fix edge cases
jcjaskula-aws Nov 24, 2023
dec59aa
fix to_unitary
jcjaskula-aws Nov 24, 2023
ef91d3d
temporary fix that checks classname
jcjaskula-aws Nov 25, 2023
dfdecfe
clean up test conditions
jcjaskula-aws Nov 26, 2023
e5eaa21
change logic according to feedback
jcjaskula-aws Nov 28, 2023
b8f0f33
update docstring
jcjaskula-aws Nov 28, 2023
244d708
clean tests
jcjaskula-aws Nov 28, 2023
c185e41
update tests
jcjaskula-aws Nov 28, 2023
4efb8bc
replace control symbols
jcjaskula-aws Nov 30, 2023
ccb81fa
use box drawing characters
jcjaskula-aws Nov 30, 2023
4aa7545
Revert "use box drawing characters"
jcjaskula-aws Dec 1, 2023
c2291f8
Revert "replace control symbols"
jcjaskula-aws Dec 1, 2023
9386bca
simplify all gphase case
jcjaskula-aws Dec 1, 2023
ecbdff1
change preprare_y_axis function name
jcjaskula-aws Dec 3, 2023
696974d
Merge branch 'main' into jcjaskula-aws/add_u_gate
jcjaskula-aws Dec 11, 2023
ad1053f
create an helper function to compute the global phase
jcjaskula-aws Dec 11, 2023
cb6baac
make control_basis_state more explicit
jcjaskula-aws Dec 11, 2023
52ce20d
add comment and clean grouping
jcjaskula-aws Dec 11, 2023
d61a0d1
add test_only_neg_control_qubits
jcjaskula-aws Dec 11, 2023
b14c03b
parametrize test_one_gate_with_global_phase
jcjaskula-aws Dec 12, 2023
095fb68
reformat
jcjaskula-aws Dec 12, 2023
8ebb0ce
change to printing with fixed precision
jcjaskula-aws Dec 12, 2023
35a92cd
Merge branch 'main' into jcjaskula-aws/add_u_gate
jcjaskula-aws Dec 18, 2023
0626370
Merge branch 'main' into jcjaskula-aws/add_u_gate
jcjaskula-aws Dec 18, 2023
304a01d
Merge branch 'main' into jcjaskula-aws/add_u_gate
jcjaskula-aws Dec 20, 2023
b6e9563
fix docstring
jcjaskula-aws Dec 20, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 23 additions & 3 deletions src/braket/circuits/ascii_circuit_diagram.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
from braket.circuits.instruction import Instruction
from braket.circuits.noise import Noise
from braket.circuits.result_type import ResultType
from braket.registers.qubit import Qubit
from braket.registers.qubit_set import QubitSet


Expand Down Expand Up @@ -84,6 +85,9 @@ def build_diagram(circuit: cir.Circuit) -> str:
# Time on top and bottom
lines.append(lines[0])

if circuit.global_phase:
lines.append(f"\nGlobal phase: {circuit.global_phase}")

# Additional result types line on bottom
if additional_result_types:
lines.append(f"\nAdditional result types: {', '.join(additional_result_types)}")
Expand Down Expand Up @@ -115,8 +119,8 @@ def _ascii_group_items(
groupings = []
for item in items:
# Can only print Gate and Noise operators for instructions at the moment
if isinstance(item, Instruction) and not isinstance(
item.operator, (Gate, Noise, CompilerDirective)
if isinstance(item, Instruction) and (
not isinstance(item.operator, (Gate, Noise, CompilerDirective))
):
continue

Expand Down Expand Up @@ -258,6 +262,10 @@ def _ascii_diagram_column(
else:
target_qubits = item.target
control_qubits = getattr(item, "control", QubitSet())
map_control_qubit_states = AsciiCircuitDiagram._build_map_control_qubits(
item, control_qubits
)

target_and_control = target_qubits.union(control_qubits)
qubits = QubitSet(range(min(target_and_control), max(target_and_control) + 1))

Expand Down Expand Up @@ -288,7 +296,7 @@ def _ascii_diagram_column(
else ascii_symbols[item_qubit_index]
)
elif qubit in control_qubits:
symbols[qubit] = "C"
symbols[qubit] = "C" if map_control_qubit_states[qubit] else "N"
jcjaskula-aws marked this conversation as resolved.
Show resolved Hide resolved
else:
symbols[qubit] = "|"

Expand All @@ -305,3 +313,15 @@ def _ascii_diagram_column(
symbols[qubit], fill="-", align="<", width=symbols_width + 1
)
return output

@staticmethod
def _build_map_control_qubits(item: Instruction, control_qubits: QubitSet) -> dict(Qubit, int):
control_state = getattr(item, "control_state", None)
if control_state is not None:
jcjaskula-aws marked this conversation as resolved.
Show resolved Hide resolved
map_control_qubit_states = {
qubit: state for qubit, state in zip(control_qubits, control_state)
}
else:
map_control_qubit_states = {qubit: 1 for qubit in control_qubits}

return map_control_qubit_states
31 changes: 30 additions & 1 deletion src/braket/circuits/basis_state.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from functools import singledispatch
from typing import Optional, Union
from typing import Any, Optional, Union

import numpy as np

Expand Down Expand Up @@ -33,6 +33,35 @@ def __iter__(self):
def __eq__(self, other):
return self.state == other.state

def __str__(self):
return self.as_string

def __repr__(self):
return f'BasisState("{self.as_string}")'

def __getitem__(self, item):
return BasisState(self.state[item])

def index(self, value: Any) -> int:
return list(self.state).index(value)

def pop(self, index: Optional[int] = None) -> int:
"""Removes and returns item at index.

Args:
index (Optional[int]): index of the object to remove (default last).

Returns:
int: removed item.
"""
if index is None:
item = self.state[-1]
self.state = self.state[:-1]
else:
item = self.state[index]
self.state = self.state[:index] + self.state[index + 1 :]
return item


BasisStateInput = Union[int, list[int], str, BasisState]

Expand Down
11 changes: 9 additions & 2 deletions src/braket/circuits/braket_program_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,15 @@ def is_builtin_gate(self, name: str) -> bool:
user_defined_gate = self.is_user_defined_gate(name)
return name in BRAKET_GATES and not user_defined_gate

def add_phase_instruction(self, target: tuple[int], phase_value: int) -> None:
raise NotImplementedError
def add_phase_instruction(self, target: tuple[int], phase_value: float) -> None:
"""Add a global phase to the circuit.

Args:
target (tuple[int]): Unused
phase_value (float): The phase value to be applied
"""
instruction = Instruction(BRAKET_GATES["gphase"](phase_value))
self._circuit.add_instruction(instruction)

def add_gate_instruction(
self, gate_name: str, target: tuple[int], *params, ctrl_modifiers: list[int], power: float
Expand Down
12 changes: 11 additions & 1 deletion src/braket/circuits/circuit.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,11 @@ def depth(self) -> int:
"""int: Get the circuit depth."""
return self._moments.depth

@property
def global_phase(self) -> float:
"""int: Get the circuit depth."""
jcjaskula-aws marked this conversation as resolved.
Show resolved Hide resolved
return self._moments._global_phase

@property
def instructions(self) -> list[Instruction]:
"""Iterable[Instruction]: Get an `iterable` of instructions in the circuit."""
Expand Down Expand Up @@ -1196,6 +1201,9 @@ def _to_openqasm(
]
)

if self.global_phase:
ir_instructions.append(f"gphase({self.global_phase});")
jcjaskula-aws marked this conversation as resolved.
Show resolved Hide resolved

if self.result_types:
ir_instructions.extend(
[
Expand Down Expand Up @@ -1423,7 +1431,9 @@ def to_unitary(self) -> np.ndarray:
qubits = self.qubits
if not qubits:
return np.zeros(0, dtype=complex)
return calculate_unitary_big_endian(self.instructions, qubits)
return calculate_unitary_big_endian(self.instructions, qubits) * np.exp(
1j * self.global_phase
)
jcjaskula-aws marked this conversation as resolved.
Show resolved Hide resolved

@property
def qubits_frozen(self) -> bool:
Expand Down
2 changes: 1 addition & 1 deletion src/braket/circuits/gate.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ def _to_openqasm(

return (
f"{inv_prefix}{power_prefix}{control_prefix}"
f"{self._qasm_name}{param_string} {', '.join(qubits)};"
f"{self._qasm_name}{param_string}{','.join([f' {qubit}' for qubit in qubits])};"
jcjaskula-aws marked this conversation as resolved.
Show resolved Hide resolved
)

@property
Expand Down
Loading
Loading