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

Deprecate the ActOnArgs._on_* methods #5224

Merged
merged 7 commits into from
Apr 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
18 changes: 10 additions & 8 deletions cirq-core/cirq/protocols/act_on_protocol_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,19 @@
from cirq.ops.raw_types import TSelf


class DummyQuantumState(cirq.QuantumStateRepresentation):
def copy(self, deep_copy_buffers=True):
pass

def measure(self, axes, seed=None):
pass


class DummyActOnArgs(cirq.ActOnArgs):
def __init__(self, fallback_result: Any = NotImplemented, measurements=None):
super().__init__(np.random.RandomState())
if measurements is None:
measurements = []
self.measurements = measurements
def __init__(self, fallback_result: Any = NotImplemented):
super().__init__(np.random.RandomState(), state=DummyQuantumState())
self.fallback_result = fallback_result

def _perform_measurement(self, qubits):
return self.measurements # coverage: ignore

def _act_on_fallback_(
self,
action: Any,
Expand Down
36 changes: 35 additions & 1 deletion cirq-core/cirq/sim/act_on_args.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
import numpy as np

from cirq import protocols, value
from cirq._compat import deprecated
from cirq._compat import _warn_or_error, deprecated
from cirq.protocols.decompose_protocol import _try_decompose_into_operations_and_qubits
from cirq.sim.operation_target import OperationTarget

Expand Down Expand Up @@ -78,6 +78,8 @@ def __init__(
}
)
self._state = state
if state is None:
_warn_or_error('This function will require a valid `state` input in cirq v0.16.')

@property
def prng(self) -> np.random.RandomState:
Expand Down Expand Up @@ -147,9 +149,17 @@ def copy(self: TSelf, deep_copy_buffers: bool = True) -> TSelf:
if self._state is not None:
args._state = self._state.copy(deep_copy_buffers=deep_copy_buffers)
else:
_warn_or_error(
'Pass a `QuantumStateRepresentation` into the `ActOnArgs` constructor. The `_on_`'
' overrides will be removed in cirq v0.16.'
)
self._on_copy(args, deep_copy_buffers)
return args

@deprecated(
deadline='v0.16',
fix='Pass a `QuantumStateRepresentation` into the `ActOnArgs` constructor.',
)
def _on_copy(self: TSelf, args: TSelf, deep_copy_buffers: bool = True):
"""Subclasses should implement this with any additional state copy
functionality."""
Expand All @@ -164,10 +174,18 @@ def kronecker_product(self: TSelf, other: TSelf, *, inplace=False) -> TSelf:
if self._state is not None and other._state is not None:
args._state = self._state.kron(other._state)
else:
_warn_or_error(
'Pass a `QuantumStateRepresentation` into the `ActOnArgs` constructor. The `_on_`'
' overrides will be removed in cirq v0.16.'
)
self._on_kronecker_product(other, args)
args._set_qubits(self.qubits + other.qubits)
return args

@deprecated(
deadline='v0.16',
fix='Pass a `QuantumStateRepresentation` into the `ActOnArgs` constructor.',
)
def _on_kronecker_product(self: TSelf, other: TSelf, target: TSelf):
"""Subclasses should implement this with any additional state product
functionality, if supported."""
Expand Down Expand Up @@ -204,6 +222,10 @@ def factor(
extracted._state = e
remainder._state = r
else:
_warn_or_error(
'Pass a `QuantumStateRepresentation` into the `ActOnArgs` constructor. The `_on_`'
' overrides will be removed in cirq v0.16.'
)
self._on_factor(qubits, extracted, remainder, validate, atol)
extracted._set_qubits(qubits)
remainder._set_qubits([q for q in self.qubits if q not in qubits])
Expand All @@ -214,6 +236,10 @@ def allows_factoring(self):
"""Subclasses that allow factorization should override this."""
return self._state.supports_factor if self._state is not None else False

@deprecated(
deadline='v0.16',
fix='Pass a `QuantumStateRepresentation` into the `ActOnArgs` constructor.',
)
def _on_factor(
self: TSelf,
qubits: Sequence['cirq.Qid'],
Expand Down Expand Up @@ -247,10 +273,18 @@ def transpose_to_qubit_order(
if self._state is not None:
args._state = self._state.reindex(self.get_axes(qubits))
else:
_warn_or_error(
'Pass a `QuantumStateRepresentation` into the `ActOnArgs` constructor. The `_on_`'
' overrides will be removed in cirq v0.16.'
)
self._on_transpose_to_qubit_order(qubits, args)
args._set_qubits(qubits)
return args

@deprecated(
deadline='v0.16',
fix='Pass a `QuantumStateRepresentation` into the `ActOnArgs` constructor.',
)
def _on_transpose_to_qubit_order(self: TSelf, qubits: Sequence['cirq.Qid'], target: TSelf):
"""Subclasses should implement this with any additional state transpose
functionality, if supported."""
Expand Down
31 changes: 23 additions & 8 deletions cirq-core/cirq/sim/act_on_args_container_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,40 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from typing import Any, Dict, List, Optional, Sequence
from typing import Any, Dict, Optional, Sequence

import cirq


class EmptyQuantumState(cirq.QuantumStateRepresentation):
def copy(self, deep_copy_buffers=True):
return self

def measure(self, axes, seed=None):
return [0] * len(axes)

@property
def supports_factor(self):
return True

def kron(self, other):
return self

def factor(self, axes, *, validate=True, atol=1e-07):
return self, self

def reindex(self, axes):
return self


class EmptyActOnArgs(cirq.ActOnArgs):
def __init__(self, qubits, classical_data):
super().__init__(
state=EmptyQuantumState(),
qubits=qubits,
classical_data=classical_data,
)

def _perform_measurement(self, qubits: Sequence[cirq.Qid]) -> List[int]:
return [0] * len(qubits)

def _act_on_fallback_(
self,
action: Any,
Expand All @@ -34,10 +53,6 @@ def _act_on_fallback_(
) -> bool:
return True

@property
def allows_factoring(self):
return True


q0, q1, q2 = qs3 = cirq.LineQubit.range(3)
qs2 = cirq.LineQubit.range(2)
Expand Down
62 changes: 58 additions & 4 deletions cirq-core/cirq/sim/act_on_args_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,21 @@
from cirq.sim import act_on_args


class DummyArgs(cirq.ActOnArgs):
def __init__(self):
super().__init__(qubits=cirq.LineQubit.range(2))
class DummyQuantumState(cirq.QuantumStateRepresentation):
def copy(self, deep_copy_buffers=True):
pass

def _perform_measurement(self, qubits):
def measure(self, axes, seed=None):
return [5, 3]

def reindex(self, axes):
return self


class DummyArgs(cirq.ActOnArgs):
def __init__(self):
super().__init__(state=DummyQuantumState(), qubits=cirq.LineQubit.range(2))

def _act_on_fallback_(
self,
action: Any,
Expand Down Expand Up @@ -95,3 +103,49 @@ def test_field_getters():
assert args.qubit_map == {q: i for i, q in enumerate(cirq.LineQubit.range(2))}
with cirq.testing.assert_deprecated('always returns False', deadline='v0.16'):
assert not args.ignore_measurement_results


def test_on_methods_deprecated():
class OldStyleArgs(cirq.ActOnArgs):
def _act_on_fallback_(self, action, qubits, allow_decompose=True):
pass

with cirq.testing.assert_deprecated('state', deadline='v0.16'):
args = OldStyleArgs()
with cirq.testing.assert_deprecated('_on_', deadline='v0.16', count=2):
_ = args.copy()
with cirq.testing.assert_deprecated('_on_', deadline='v0.16', count=2):
_ = args.kronecker_product(args)
with cirq.testing.assert_deprecated('_on_', deadline='v0.16', count=2):
_ = args.factor([])
with cirq.testing.assert_deprecated('_on_', deadline='v0.16', count=2):
_ = args.transpose_to_qubit_order([])


def test_on_methods_deprecated_if_implemented():
class OldStyleArgs(cirq.ActOnArgs):
def _act_on_fallback_(self, action, qubits, allow_decompose=True):
pass

def _on_copy(self, args, deep_copy_buffers=True):
pass

def _on_kronecker_product(self, other, target):
pass

def _on_factor(self, qubits, extracted, remainder, validate=True, atol=1e-07):
pass

def _on_transpose_to_qubit_order(self, qubits, target):
pass

with cirq.testing.assert_deprecated('state', deadline='v0.16'):
args = OldStyleArgs()
with cirq.testing.assert_deprecated('_on_', deadline='v0.16'):
_ = args.copy()
with cirq.testing.assert_deprecated('_on_', deadline='v0.16'):
_ = args.kronecker_product(args)
with cirq.testing.assert_deprecated('_on_', deadline='v0.16'):
_ = args.factor([])
with cirq.testing.assert_deprecated('_on_', deadline='v0.16'):
_ = args.transpose_to_qubit_order([])