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.gate import Gate 

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# InstructionOperator is a type alias, and it can be expanded to include other operators 

26InstructionOperator = Gate 

27 

28 

29class Instruction: 

30 """ 

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

32 """ 

33 

34 def __init__(self, operator: InstructionOperator, target: QubitSetInput): 

35 """ 

36 InstructionOperator includes objects of type Gate only. 

37 

38 Args: 

39 operator (InstructionOperator): Operator for the instruction. 

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

41 applied to. 

42 

43 Raises: 

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

45 or QubitSet class requirements. 

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

47 `typing`. 

48 

49 Examples: 

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

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

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

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

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

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

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

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

58 """ 

59 if not operator: 

60 raise ValueError("Operator cannot be empty") 

61 self._operator = operator 

62 self._target = QubitSet(target) 

63 

64 @property 

65 def operator(self) -> InstructionOperator: 

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

67 return self._operator 

68 

69 @property 

70 def target(self) -> QubitSet: 

71 """ 

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

73 

74 Note: 

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

76 """ 

77 return self._target 

78 

79 def to_ir(self): 

80 """ 

81 Converts the operator into the canonical intermediate representation. 

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

83 """ 

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

85 

86 def copy( 

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

88 ) -> Instruction: 

89 """ 

90 Return a shallow copy of the instruction. 

91 

92 Note: 

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

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

95 

96 Args: 

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

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

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

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

101 instruction. 

102 

103 Returns: 

104 Instruction: A shallow copy of the instruction. 

105 

106 Raises: 

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

108 

109 Examples: 

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

111 >>> new_instr = instr.copy() 

112 >>> new_instr.target 

113 QubitSet(Qubit(0)) 

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

115 >>> new_instr.target 

116 QubitSet(Qubit(5)) 

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

118 >>> new_instr.target 

119 QubitSet(Qubit(5)) 

120 """ 

121 if target_mapping and target is not None: 

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

123 elif target is not None: 

124 return Instruction(self._operator, target) 

125 else: 

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

127 

128 def __repr__(self): 

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

130 

131 def __eq__(self, other): 

132 if isinstance(other, Instruction): 

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

134 return NotImplemented