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 __future__ import annotations 

15 

16from typing import Dict 

17 

18from braket.circuits.operator import Operator 

19from braket.circuits.qubit import QubitInput 

20from braket.circuits.qubit_set import QubitSet, QubitSetInput 

21 

22# TODO: Add parameters support 

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

24 

25 

26class Instruction: 

27 """ 

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

29 """ 

30 

31 def __init__(self, operator: Operator, target: QubitSetInput): 

32 """ 

33 Args: 

34 operator (Operator): Operator for the instruction. 

35 target (int, Qubit, or iterable of int / Qubit): Target qubits that the operator is 

36 applied to. 

37 

38 Raises: 

39 ValueError: If `operator` is empty or any integer in `target` does not meet the Qubit 

40 or QubitSet class requirements. 

41 TypeError: If a Qubit class can't be constructed from `target` due to an incorrect 

42 `typing`. 

43 

44 Examples: 

45 >>> Instruction(Gate.CNot(), [0, 1]) 

46 Instruction('operator': CNOT, 'target': QubitSet(Qubit(0), Qubit(1))) 

47 >>> instr = Instruction(Gate.CNot()), QubitSet([0, 1])]) 

48 Instruction('operator': CNOT, 'target': QubitSet(Qubit(0), Qubit(1))) 

49 >>> instr = Instruction(Gate.H(), 0) 

50 Instruction('operator': H, 'target': QubitSet(Qubit(0),)) 

51 >>> instr = Instruction(Gate.Rx(0.12), 0) 

52 Instruction('operator': Rx, 'target': QubitSet(Qubit(0),)) 

53 """ 

54 if not operator: 

55 raise ValueError("Operator cannot be empty") 

56 self._operator = operator 

57 self._target = QubitSet(target) 

58 

59 @property 

60 def operator(self) -> Operator: 

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

62 return self._operator 

63 

64 @property 

65 def target(self) -> QubitSet: 

66 """ 

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

68 

69 Note: 

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

71 """ 

72 return self._target 

73 

74 def to_ir(self): 

75 """ 

76 Converts the operator into the canonical intermediate representation. 

77 If the operator is passed in a request, this method is called before it is passed. 

78 """ 

79 return self._operator.to_ir([int(qubit) for qubit in self._target]) 

80 

81 def copy( 

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

83 ) -> Instruction: 

84 """ 

85 Return a shallow copy of the instruction. 

86 

87 Note: 

88 If `target_mapping` is specified, then `self.target` is mapped to the specified 

89 qubits. This is useful apply an instruction to a circuit and change the target qubits. 

90 

91 Args: 

92 target_mapping (dictionary[int or Qubit, int or Qubit], optional): A dictionary of 

93 qubit mappings to apply to the target. Key is the qubit in this `target` and the 

94 value is what the key is changed to. Default = {}. 

95 target (int, Qubit, or iterable of int / Qubit, optional): Target qubits for the new 

96 instruction. 

97 

98 Returns: 

99 Instruction: A shallow copy of the instruction. 

100 

101 Raises: 

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

103 

104 Examples: 

105 >>> instr = Instruction(Gate.H(), 0) 

106 >>> new_instr = instr.copy() 

107 >>> new_instr.target 

108 QubitSet(Qubit(0)) 

109 >>> new_instr = instr.copy(target_mapping={0: 5}) 

110 >>> new_instr.target 

111 QubitSet(Qubit(5)) 

112 >>> new_instr = instr.copy(target=[5]) 

113 >>> new_instr.target 

114 QubitSet(Qubit(5)) 

115 """ 

116 if target_mapping and target is not None: 

117 raise TypeError("Only 'target_mapping' or 'target' can be supplied, but not both.") 

118 elif target is not None: 

119 return Instruction(self._operator, target) 

120 else: 

121 return Instruction(self._operator, self._target.map(target_mapping)) 

122 

123 def __repr__(self): 

124 return f"Instruction('operator': {self._operator}, 'target': {self._target})" 

125 

126 def __eq__(self, other): 

127 if isinstance(other, Instruction): 

128 return (self._operator, self._target) == (other._operator, other._target) 

129 return NotImplemented