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

Add decomposition for CCZ gate and IonQTargetGateset when qubits are all-to-all connected #6095

Merged
merged 21 commits into from
Aug 7, 2023
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
aa8077f
Add all-to-all decomposition for CCZ gate
yinghui-hu May 16, 2023
d5f8c98
Fix format check and type check
yinghui-hu May 16, 2023
9555f31
Revert type check change
yinghui-hu May 16, 2023
219c710
Ignore type check for `global_phase`
yinghui-hu May 16, 2023
e31bc96
Expect test_custom_value_not_implemented to pass
yinghui-hu May 16, 2023
1d85158
Sync test_custom_value_not_implemented
yinghui-hu May 16, 2023
a89bf4c
Merge branch 'quantumlib:master' into all_connectivity_decompose
yinghui-hu May 16, 2023
397b9a7
Merge branch 'quantumlib:master' into all_connectivity_decompose
yinghui-hu May 23, 2023
e12eda1
IonQTargetGateset._decompose_multi_qubit_operation
yinghui-hu May 23, 2023
79f9c3a
Fix format and type check
yinghui-hu May 23, 2023
cf3c640
Fix type for input `qubits`
yinghui-hu May 23, 2023
eea47ce
Merge branch 'quantumlib:master' into all_connectivity_decompose
yinghui-hu Jun 2, 2023
b4ca8d7
Add test for ValueError
yinghui-hu Jun 2, 2023
f3bf72d
Merge branch 'master' into all_connectivity_decompose
yinghui-hu Jul 19, 2023
8c5afe7
Resolve comments
yinghui-hu Jul 19, 2023
4d835d7
Add a new line after summary line and before description
yinghui-hu Jul 19, 2023
6a1f140
Fix format, type and lint
yinghui-hu Jul 19, 2023
02c49a0
Ignore type check
yinghui-hu Jul 19, 2023
d31fc77
Merge branch 'master' into all_connectivity_decompose
yinghui-hu Jul 21, 2023
210f720
Merge branch 'master' into all_connectivity_decompose
yinghui-hu Jul 27, 2023
ca5b113
Merge branch 'master' into all_connectivity_decompose
yinghui-hu Aug 6, 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
1 change: 1 addition & 0 deletions cirq-core/cirq/ops/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@
CCXPowGate,
CCZ,
CCZPowGate,
decompose_all_to_all_connect_ccz_gate,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove from cirq/ops/__init__.py

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

CSWAP,
CSwapGate,
FREDKIN,
Expand Down
49 changes: 49 additions & 0 deletions cirq-core/cirq/ops/three_qubit_gates.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,55 @@ def controlled(
)


def decompose_all_to_all_connect_ccz_gate(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move this decomposition and corresponding test to cirq-ionq/cirq_ionq/ionq_gateset.py.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

ccz_gate: 'CCZPowGate', qubits: Tuple['cirq.Qid', ...]
) -> 'cirq.OP_TREE':
"""If qubits are all-to-all connected, e.g. qubits in the same ion trap,
the decomposition will be:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary line in the docstring should be a single line with <= 100 characters followed by an empty newline and then a detailed description if needed. Please update here and elsewhere

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Thanks for the guide.


0: ──────────────@──────────────────@───@───p──────@───
│ │ │ │
1: ───@──────────┼───────@───p──────┼───X───p^-1───X───
│ │ │ │
2: ───X───p^-1───X───p───X───p^-1───X───p──────────────

where p = T**ccz_gate._exponent
"""
if len(qubits) != 3:
raise ValueError(f'Expect 3 qubits for CCZ gate, got {len(qubits)} qubits.')

a, b, c = qubits

p = common_gates.T**ccz_gate._exponent
global_phase = 1j ** (2 * ccz_gate.global_shift * ccz_gate._exponent)
global_phase = (
complex(global_phase)
if protocols.is_parameterized(global_phase) and global_phase.is_complex # type: ignore
else global_phase
)
global_phase_operation = (
[global_phase_op.global_phase_operation(global_phase)]
if protocols.is_parameterized(global_phase) or abs(global_phase - 1.0) > 0
else []
)

return global_phase_operation + [
common_gates.CNOT(b, c),
p(c) ** -1,
common_gates.CNOT(a, c),
p(c),
common_gates.CNOT(b, c),
p(c) ** -1,
common_gates.CNOT(a, c),
p(b),
p(c),
common_gates.CNOT(a, b),
p(a),
p(b) ** -1,
common_gates.CNOT(a, b),
]


@value.value_equality()
class ThreeQubitDiagonalGate(raw_types.Gate):
r"""A three qubit gate whose unitary is given by a diagonal $8 \times 8$ matrix.
Expand Down
22 changes: 22 additions & 0 deletions cirq-core/cirq/ops/three_qubit_gates_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,28 @@ def test_decomposition_respects_locality(gate):
dev.validate_circuit(circuit)


def test_decomposition_all_to_all_connectivity():
"""This function only accepts 3 qubits as input"""
with pytest.raises(ValueError):
decompose_result = cirq.ops.decompose_all_to_all_connect_ccz_gate(
cirq.CCZ, cirq.LineQubit.range(4)
)

decompose_result = cirq.ops.decompose_all_to_all_connect_ccz_gate(
cirq.CCZ, cirq.LineQubit.range(3)
)
cirq.testing.assert_has_diagram(
cirq.Circuit(decompose_result),
"""
0: ──────────────@──────────────────@───@───T──────@───
│ │ │ │
1: ───@──────────┼───────@───T──────┼───X───T^-1───X───
│ │ │ │
2: ───X───T^-1───X───T───X───T^-1───X───T──────────────
""",
)


def test_diagram():
a, b, c, d = cirq.LineQubit.range(4)
circuit = cirq.Circuit(
Expand Down
12 changes: 10 additions & 2 deletions cirq-ionq/cirq_ionq/ionq_gateset.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,20 @@ def _decompose_two_qubit_operation(self, op: cirq.Operation, _) -> cirq.OP_TREE:
temp, k=1, rewriter=lambda op: self._decompose_single_qubit_operation(op, -1)
).all_operations()

def _decompose_multi_qubit_operation(self, op: cirq.Operation, _) -> cirq.OP_TREE:
if isinstance(op.gate, cirq.CCZPowGate):
return cirq.ops.decompose_all_to_all_connect_ccz_gate(op.gate, op.qubits)
return NotImplemented

@property
def preprocess_transformers(self) -> List['cirq.TRANSFORMER']:
"""List of transformers which should be run before decomposing individual operations."""
"""List of transformers which should be run before decomposing individual operations.
yinghui-hu marked this conversation as resolved.
Show resolved Hide resolved
Decompose to three qubit gates because three qubit gates have different decomposition
for all-to-all connectivity between qubits.
"""
return [
cirq.create_transformer_with_kwargs(
cirq.expand_composite, no_decomp=lambda op: cirq.num_qubits(op) <= self.num_qubits
cirq.expand_composite, no_decomp=lambda op: cirq.num_qubits(op) <= 3
)
]

Expand Down
21 changes: 21 additions & 0 deletions cirq-ionq/cirq_ionq/ionq_gateset_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,3 +131,24 @@ def test_decompose_parameterized_operation():
atol=1e-6,
)
assert ionq_target_gateset.validate(decomposed_circuit)


def test_decompose_toffoli_gate():
circuit = cirq.Circuit(cirq.TOFFOLI(*cirq.LineQubit.range(3)))
decomposed_circuit = cirq.optimize_for_target_gateset(
circuit, gateset=ionq_target_gateset, ignore_failures=False
)
cirq.testing.assert_circuits_with_terminal_measurements_are_equivalent(
circuit, decomposed_circuit, atol=1e-8
)
assert ionq_target_gateset.validate(decomposed_circuit)
cirq.testing.assert_has_diagram(
decomposed_circuit,
"""
0: ──────────────────@──────────────────@───@───T──────@───
│ │ │ │
1: ───────@──────────┼───────@───T──────┼───X───T^-1───X───
│ │ │ │
2: ───H───X───T^-1───X───T───X───T^-1───X───T───H──────────
""",
)