-
Notifications
You must be signed in to change notification settings - Fork 988
/
devices.py
77 lines (61 loc) · 3.06 KB
/
devices.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# Copyright 2018 The Cirq Developers
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# 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.
# TODO(#6171): enable the check and fix pylint errors
# pylint: disable=consider-using-f-string
from typing import Union, TYPE_CHECKING
import abc
from cirq import circuits, devices, ops
from cirq.contrib.acquaintance.gates import AcquaintanceOpportunityGate, SwapNetworkGate
from cirq.contrib.acquaintance.bipartite import BipartiteSwapNetworkGate
from cirq.contrib.acquaintance.shift_swap_network import ShiftSwapNetworkGate
from cirq.contrib.acquaintance.permutation import PermutationGate
if TYPE_CHECKING:
import cirq
class AcquaintanceDevice(devices.Device, metaclass=abc.ABCMeta):
"""A device that contains only acquaintance and permutation gates."""
gate_types = (AcquaintanceOpportunityGate, PermutationGate)
def validate_operation(self, operation: 'cirq.Operation') -> None:
if not (
isinstance(operation, ops.GateOperation) and isinstance(operation.gate, self.gate_types)
):
raise ValueError(
'not (isinstance({0!r}, {1!r}) and '
'ininstance({0!r}.gate, {2!r})'.format(operation, ops.Operation, self.gate_types)
)
def get_acquaintance_size(obj: Union[circuits.Circuit, ops.Operation]) -> int:
"""The maximum number of qubits to be acquainted with each other."""
if isinstance(obj, circuits.Circuit):
return max(tuple(get_acquaintance_size(op) for op in obj.all_operations()) or (0,))
if not isinstance(obj, ops.Operation):
raise TypeError('not isinstance(obj, (Circuit, Operation))')
if not isinstance(obj, ops.GateOperation):
return 0
if isinstance(obj.gate, AcquaintanceOpportunityGate):
return len(obj.qubits)
if isinstance(obj.gate, BipartiteSwapNetworkGate):
return 2
if isinstance(obj.gate, ShiftSwapNetworkGate):
return obj.gate.acquaintance_size()
if isinstance(obj.gate, SwapNetworkGate):
if obj.gate.acquaintance_size is None:
return sum(sorted(obj.gate.part_lens)[-2:])
if (obj.gate.acquaintance_size - 1) in obj.gate.part_lens:
return obj.gate.acquaintance_size
sizer = getattr(obj.gate, '_acquaintance_size_', None)
return 0 if sizer is None else sizer(len(obj.qubits))
class _UnconstrainedAcquaintanceDevice(AcquaintanceDevice):
"""An acquaintance device with no constraints other than of the gate types."""
def __repr__(self) -> str:
return 'UnconstrainedAcquaintanceDevice' # coverage: ignore
UnconstrainedAcquaintanceDevice = _UnconstrainedAcquaintanceDevice()