Coverage for src/braket/circuits/instruction.py : 100%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# Copyright 2019-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2#
3# Licensed under the Apache License, Version 2.0 (the "License"). You
4# may not use this file except in compliance with the License. A copy of
5# the License is located at
6#
7# http://aws.amazon.com/apache2.0/
8#
9# or in the "license" file accompanying this file. This file is
10# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
11# ANY KIND, either express or implied. See the License for the specific
12# language governing permissions and limitations under the License.
14from typing import Dict
16from braket.circuits.operator import Operator
17from braket.circuits.qubit import QubitInput
18from braket.circuits.qubit_set import QubitSet, QubitSetInput
20# TODO: Add parameters support
21# TODO: Rename to QuantumInstruction, and change Operator to Gate, then rename "target" to "qubits"
24class Instruction:
25 """
26 An instruction is a quantum directive that describes the task to perform on a quantum device.
27 """
29 def __init__(self, operator: Operator, target: QubitSetInput):
30 """
31 Args:
32 operator (Operator): Operator for the instruction.
33 target (int, Qubit, or iterable of int / Qubit): Target qubits that the operator is
34 applied to.
36 Raises:
37 ValueError: If `operator` is empty or any integer in `target` does not meet the Qubit
38 or QubitSet class requirements.
39 TypeError: If a Qubit class can't be constructed from `target` due to an incorrect
40 `typing`.
42 Examples:
43 >>> Instruction(Gate.CNot(), [0, 1])
44 Instruction('operator': CNOT, 'target': QubitSet(Qubit(0), Qubit(1)))
45 >>> instr = Instruction(Gate.CNot()), QubitSet([0, 1])])
46 Instruction('operator': CNOT, 'target': QubitSet(Qubit(0), Qubit(1)))
47 >>> instr = Instruction(Gate.H(), 0)
48 Instruction('operator': H, 'target': QubitSet(Qubit(0),))
49 >>> instr = Instruction(Gate.Rx(0.12), 0)
50 Instruction('operator': Rx, 'target': QubitSet(Qubit(0),))
51 """
52 if not operator:
53 raise ValueError("Operator cannot be empty")
54 self._operator = operator
55 self._target = QubitSet(target)
57 @property
58 def operator(self) -> Operator:
59 """Operator: The operator for the instruction, for example, `Gate`."""
60 return self._operator
62 @property
63 def target(self) -> QubitSet:
64 """
65 QubitSet: Target qubits that the operator is applied to.
67 Note:
68 Don't mutate this property, any mutations can have unexpected consequences.
69 """
70 return self._target
72 def to_ir(self):
73 """
74 Converts the operator into the canonical intermediate representation.
75 If the operator is passed in a request, this method is called before it is passed.
76 """
77 return self.operator.to_ir(self.target)
79 def copy(
80 self, target_mapping: Dict[QubitInput, QubitInput] = {}, target: QubitSetInput = None
81 ) -> "Instruction":
82 """
83 Return a shallow copy of the instruction.
85 Note:
86 If `target_mapping` is specified, then `self.target` is mapped to the specified
87 qubits. This is useful apply an instruction to a circuit and change the target qubits.
89 Args:
90 target_mapping (dictionary[int or Qubit, int or Qubit], optional): A dictionary of
91 qubit mappings to apply to the target. Key is the qubit in this `target` and the
92 value is what the key is changed to. Default = {}.
93 target (int, Qubit, or iterable of int / Qubit, optional): Target qubits for the new
94 instruction.
96 Returns:
97 Instruction: A shallow copy of the instruction.
99 Raises:
100 TypeError: If both `target_mapping` and `target` are supplied.
102 Examples:
103 >>> instr = Instruction(Gate.H(), 0)
104 >>> new_instr = instr.copy()
105 >>> new_instr.target
106 QubitSet(Qubit(0))
107 >>> new_instr = instr.copy(target_mapping={0: 5})
108 >>> new_instr.target
109 QubitSet(Qubit(5))
110 >>> new_instr = instr.copy(target=[5])
111 >>> new_instr.target
112 QubitSet(Qubit(5))
113 """
114 if target_mapping and target is not None:
115 raise TypeError("Only 'target_mapping' or 'target' can be supplied, but not both.")
116 elif target is not None:
117 return Instruction(self.operator, target)
118 else:
119 return Instruction(self.operator, self.target.map(target_mapping))
121 def __repr__(self):
122 return f"Instruction('operator': {self.operator}, 'target': {self.target})"
124 def __eq__(self, other):
125 if isinstance(other, Instruction):
126 return (self.operator, self.target) == (other.operator, other.target)
127 return NotImplemented