Hide keyboard shortcuts

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. 

13 

14from typing import Dict 

15 

16from braket.circuits.operator import Operator 

17from braket.circuits.qubit import QubitInput 

18from braket.circuits.qubit_set import QubitSet, QubitSetInput 

19 

20# TODO: Add parameters support 

21# TODO: Rename to QuantumInstruction, and change Operator to Gate, then rename "target" to "qubits" 

22 

23 

24class Instruction: 

25 """ 

26 An instruction is a quantum directive that describes the task to perform on a quantum device. 

27 """ 

28 

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. 

35 

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`. 

41 

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) 

56 

57 @property 

58 def operator(self) -> Operator: 

59 """Operator: The operator for the instruction, for example, `Gate`.""" 

60 return self._operator 

61 

62 @property 

63 def target(self) -> QubitSet: 

64 """ 

65 QubitSet: Target qubits that the operator is applied to. 

66 

67 Note: 

68 Don't mutate this property, any mutations can have unexpected consequences. 

69 """ 

70 return self._target 

71 

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) 

78 

79 def copy( 

80 self, target_mapping: Dict[QubitInput, QubitInput] = {}, target: QubitSetInput = None 

81 ) -> "Instruction": 

82 """ 

83 Return a shallow copy of the instruction. 

84 

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. 

88 

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. 

95 

96 Returns: 

97 Instruction: A shallow copy of the instruction. 

98 

99 Raises: 

100 TypeError: If both `target_mapping` and `target` are supplied. 

101 

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)) 

120 

121 def __repr__(self): 

122 return f"Instruction('operator': {self.operator}, 'target': {self.target})" 

123 

124 def __eq__(self, other): 

125 if isinstance(other, Instruction): 

126 return (self.operator, self.target) == (other.operator, other.target) 

127 return NotImplemented