Skip to content

Commit 2467e39

Browse files
authored
IdentityGate optimizations for act_on and independent states (S) (#4340)
This exponentially improves perf on density matrix simulator for identity gates with several qubits. It also prevents merging independent states when an identity gate has multiple qubits.
1 parent 0f9fa3f commit 2467e39

File tree

4 files changed

+24
-1
lines changed

4 files changed

+24
-1
lines changed

cirq-core/cirq/ops/identity.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
# limitations under the License.
1414
"""IdentityGate."""
1515

16-
from typing import Any, Dict, Optional, Tuple, TYPE_CHECKING
16+
from typing import Any, Dict, Optional, Tuple, TYPE_CHECKING, Sequence
1717

1818
import numpy as np
1919
import sympy
@@ -59,6 +59,9 @@ def __init__(
5959
if len(self._qid_shape) != num_qubits:
6060
raise ValueError('len(qid_shape) != num_qubits')
6161

62+
def _act_on_(self, args: 'cirq.ActOnArgs', qubits: Sequence['cirq.Qid']):
63+
return True
64+
6265
def _qid_shape_(self) -> Tuple[int, ...]:
6366
return self._qid_shape
6467

cirq-core/cirq/ops/identity_test.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,12 @@
1313
# limitations under the License.
1414
import itertools
1515
from typing import Any
16+
from unittest import mock
1617

1718
import numpy as np
1819
import pytest
1920
import sympy
21+
2022
import cirq
2123

2224

@@ -202,3 +204,9 @@ def with_qubits(self, *new_qubits):
202204

203205
assert i * 2 == cirq.PauliString(coefficient=2)
204206
assert 1j * i == cirq.PauliString(coefficient=1j)
207+
208+
209+
def test_identity_short_circuits_act_on():
210+
args = mock.Mock(cirq.ActOnArgs)
211+
args._act_on_fallback_.side_effect = mock.Mock(side_effect=Exception('No!'))
212+
cirq.act_on(cirq.IdentityGate(1)(cirq.LineQubit(0)), args)

cirq-core/cirq/sim/act_on_args_container.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,9 @@ def apply_operation(
8282
op: 'cirq.Operation',
8383
):
8484
gate = op.gate
85+
if isinstance(gate, ops.IdentityGate):
86+
return
87+
8588
if isinstance(gate, ops.SwapPowGate) and gate.exponent % 2 == 1 and gate.global_shift == 0:
8689
q0, q1 = op.qubits
8790
args0 = self.args[q0]

cirq-core/cirq/sim/act_on_args_container_test.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,15 @@ def test_entanglement_causes_join():
9898
assert args[None] is not args[q0]
9999

100100

101+
def test_identity_does_not_join():
102+
args = create_container(qs2)
103+
assert len(set(args.values())) == 3
104+
args.apply_operation(cirq.IdentityGate(2)(q0, q1))
105+
assert len(set(args.values())) == 3
106+
assert args[q0] is not args[q1]
107+
assert args[q0] is not args[None]
108+
109+
101110
def test_measurement_causes_split():
102111
args = create_container(qs2)
103112
args.apply_operation(cirq.CNOT(q0, q1))

0 commit comments

Comments
 (0)