Reference
+ + + + + +
+ Circuit
+
+
+
+
+
+ The Circuit class is the only interface to access OpenSquirrel's features.
+ + + +Examples:
+>>> c = Circuit.from_string("version 3.0; qubit[3] q; h q[0]")
+>>> c
+version 3.0
+
+qubit[3] q
+
+h q[0]
+
+>>> c.decompose_mckay()
+>>> c
+version 3.0
+
+qubit[3] q
+
+x90 q[0]
+rz q[0], 1.5707963
+x90 q[0]
+
Source code in opensquirrel\circuit.py
+ 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 + 78 + 79 + 80 + 81 + 82 + 83 + 84 + 85 + 86 + 87 + 88 + 89 + 90 + 91 + 92 + 93 + 94 + 95 + 96 + 97 + 98 + 99 +100 +101 +102 +103 +104 |
|
+ __init__(squirrel_ir)
+
+
+
+
+ Create a circuit object from a SquirrelIR object.
+ +Source code in opensquirrel\circuit.py
+ 35 +36 +37 +38 |
|
+ __repr__()
+
+
+
+
+ Write the circuit to a cQasm3 string.
+-
+
- comments are removed +
Source code in opensquirrel\circuit.py
+ 98 + 99 +100 +101 +102 +103 +104 |
|
+ decompose_mckay()
+
+
+
+
+ Perform gate fusion on all one-qubit gates and decompose them in the McKay style.
+-
+
- all one-qubit gates on same qubit are merged together, without attempting to commute any gate +
- two-or-more-qubit gates are left as-is +
- merged one-qubit gates are decomposed according to McKay decomposition, that is: + gate ----> Rz.Rx(pi/2).Rz.Rx(pi/2).Rz +
- global phase is deemed irrelevant, therefore a simulator backend might produce different output + for the input and output circuit - those outputs should be equivalent modulo global phase. +
Source code in opensquirrel\circuit.py
+ 66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 |
|
+ from_string(cqasm3_string, gate_set=default_gate_set, gate_aliases=default_gate_aliases)
+
+
+ classmethod
+
+
+
+
+
+ Create a circuit object from a cQasm3 string. All the gates in the circuit need to be defined in
+the gates
argument.
-
+
- type-checking is performed, eliminating qubit indices errors and incoherencies +
- checks that used gates are supported and mentioned in
gates
with appropriate signatures
+ - does not support map or variables, and other things... +
- for example of
gates
dictionary, please look at TestGates.py
+
Source code in opensquirrel\circuit.py
+ 40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 |
|
+ replace(gate_name, f)
+
+
+
+
+ Manually replace occurrences of a given gate with a list of gates.
+-
+
- this can be called decomposition - but it's the least fancy version of it +
- function parameter gives the decomposition based on parameters of original gate +
Source code in opensquirrel\circuit.py
+ 79 +80 +81 +82 +83 +84 +85 +86 |
|
+ test_get_circuit_matrix()
+
+
+
+
+ Get the (large) unitary matrix corresponding to the circuit.
+-
+
- this matrix has 4**n elements, where n is the number of qubits +
- therefore this function is only here for testing purposes on small number of qubits +
- result is stored as a numpy array of complex numbers +
Source code in opensquirrel\circuit.py
+ 88 +89 +90 +91 +92 +93 +94 +95 +96 |
|
+ CircuitBuilder
+
+
+
+
+
+
+ Bases: GateLibrary
A class using the builder pattern to make construction of circuits easy from Python. +Adds corresponding gate when a method is called. Checks gates are known and called with the right arguments. +Mainly here to allow for Qiskit-style circuit construction:
+++ +++++CircuitBuilder(number_of_qubits=3).h(Qubit(0)).cnot(Qubit(0), Qubit(1)).cnot(Qubit(0), Qubit(2)).to_circuit() +version 3.0 +
++qubit[3] q + +h q[0] +cnot q[0], q[1] +cnot q[0], q[2] +
Source code in opensquirrel\circuit_builder.py
+ 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 |
|
+ get_circuit_matrix(squirrel_ir)
+
+
+
+
+ Compute the Numpy unitary matrix corresponding to the circuit. +The size of this matrix grows exponentially with the number of qubits.
+ +Source code in opensquirrel\circuit_matrix_calculator.py
+ 20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 |
|
+ QubitRangeChecker
+
+
+
+
+
+
+ Bases: CQasm3Visitor
This class checks that all qubit indices make sense in an ANTLR parse tree. +It is an instance of the ANTLR abstract syntax tree visitor class. +Therefore, method names are fixed and based on rule names in the Grammar .g4 file.
+ +Source code in opensquirrel\parsing\antlr\qubit_range_checker.py
+ 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 |
|
+ SquirrelIRCreator
+
+
+
+
+
+
+ Bases: GateLibrary
, CQasm3Visitor
This class creates a SquirrelIR object from an ANTLR parse tree. +It is an instance of the ANTLR abstract syntax tree visitor class. +Therefore, method names are fixed and based on rule names in the Grammar .g4 file.
+ +Source code in opensquirrel\parsing\antlr\squirrel_ir_creator.py
+ 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 |
|
+ squirrel_ir_from_string(s, gate_set, gate_aliases)
+
+
+
+
+ ANTLR parsing entrypoint. +Performs type checking based on provided gate semantics and check that the qubit indices are valid. +Creates the IR where each gate node is mapped to its semantic function and arguments.
+ + + +Parameters:
+Name | +Type | +Description | +Default | +
---|---|---|---|
gate_set |
+ + | +
+
+
+ The set of supported gate semantics. + |
+ + required + | +
gate_aliases |
+ + | +
+
+
+ Dictionary mapping extra gate names to their semantic. + |
+ + required + | +
Returns:
+Type | +Description | +
---|---|
+ | +
+
+
+ A corresponding SquirrelIR object. Throws in case of parsing error. + |
+
Source code in opensquirrel\parsing\antlr\squirrel_ir_from_string.py
+ 35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 |
|
+ TypeChecker
+
+
+
+
+
+
+ Bases: GateLibrary
, CQasm3Visitor
This class checks that all gate parameter types make sense in an ANTLR parse tree. +It is an instance of the ANTLR abstract syntax tree visitor class. +Therefore, method names are fixed and based on rule names in the Grammar .g4 file.
+ +Source code in opensquirrel\parsing\antlr\type_checker.py
+ 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 |
|
+ expand_ket(base_ket, reduced_ket, qubits)
+
+
+
+
+ Given a base quantum ket on n qubits and a reduced ket on a subset of those qubits, this computes the expanded ket
+where the reduction qubits and the other qubits are set based on the reduced ket and the base ket, respectively.
+Roughly equivalent to the pdep
assembly instruction (bits deposit).
Parameters:
+Name | +Type | +Description | +Default | +
---|---|---|---|
base_ket |
+
+ int
+ |
+
+
+
+ A quantum ket, represented by its corresponding non-negative integer. + By convention, qubit #0 corresponds to the least significant bit. + |
+ + required + | +
reduced_ket |
+
+ int
+ |
+
+
+
+ A quantum ket, represented by its corresponding non-negative integer. + By convention, qubit #0 corresponds to the least significant bit. + |
+ + required + | +
qubits |
+
+ List[Qubit]
+ |
+
+
+
+ The indices of the qubits to expand from the reduced ket. Order matters. + |
+ + required + | +
Returns:
+Type | +Description | +
---|---|
+ int
+ |
+
+
+
+ The non-negative integer corresponding to the expanded ket. + |
+
Examples:
+>>> expand_ket(0b00000, 0b0, [Qubit(5)]) # 0b000000
+0
+>>> expand_ket(0b00000, 0b1, [Qubit(5)]) # 0b100000
+32
+>>> expand_ket(0b00111, 0b0, [Qubit(5)]) # 0b000111
+7
+>>> expand_ket(0b00111, 0b1, [Qubit(5)]) # 0b100111
+39
+>>> expand_ket(0b0000, 0b000, [Qubit(1), Qubit(2), Qubit(3)]) # 0b0000
+0
+>>> expand_ket(0b0000, 0b001, [Qubit(1), Qubit(2), Qubit(3)]) # 0b0010
+2
+>>> expand_ket(0b0000, 0b011, [Qubit(1), Qubit(2), Qubit(3)]) # 0b0110
+6
+>>> expand_ket(0b0000, 0b101, [Qubit(1), Qubit(2), Qubit(3)]) # 0b1010
+10
+>>> expand_ket(0b0001, 0b101, [Qubit(1), Qubit(2), Qubit(3)]) # 0b1011
+11
+
Source code in opensquirrel\utils\matrix_expander.py
+ 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 +78 +79 +80 +81 +82 +83 +84 +85 +86 |
|
+ get_matrix(gate, number_of_qubits)
+
+
+
+
+ Compute the unitary matrix corresponding to the gate applied to those qubit operands, taken among any number of qubits. +This can be used for, e.g., +- testing, +- permuting the operands of multi-qubit gates, +- simulating a circuit (simulation in this way is inefficient for large numbers of qubits).
+ + + +Parameters:
+Name | +Type | +Description | +Default | +
---|---|---|---|
gate |
+
+ Gate
+ |
+
+
+
+ The gate, including the qubits on which it is operated on. + |
+ + required + | +
number_of_qubits |
+
+ int
+ |
+
+
+
+ The total number of qubits. + |
+ + required + | +
Examples:
+>>> X = lambda q: BlochSphereRotation(qubit=q, axis=(1, 0, 0), angle=math.pi, phase=math.pi / 2)
+>>> get_matrix(X(Qubit(1)), 2).astype(int) # X q[1]
+array([[0, 0, 1, 0],
+ [0, 0, 0, 1],
+ [1, 0, 0, 0],
+ [0, 1, 0, 0]])
+
>>> CNOT02 = ControlledGate(Qubit(0), X(Qubit(2)))
+>>> get_matrix(CNOT02, 3).astype(int) # CNOT q[0], q[2]
+array([[1, 0, 0, 0, 0, 0, 0, 0],
+ [0, 0, 0, 0, 0, 1, 0, 0],
+ [0, 0, 1, 0, 0, 0, 0, 0],
+ [0, 0, 0, 0, 0, 0, 0, 1],
+ [0, 0, 0, 0, 1, 0, 0, 0],
+ [0, 1, 0, 0, 0, 0, 0, 0],
+ [0, 0, 0, 0, 0, 0, 1, 0],
+ [0, 0, 0, 1, 0, 0, 0, 0]])
+>>> get_matrix(ControlledGate(Qubit(1), X(Qubit(2))), 3).astype(int) # CNOT q[1], q[2]
+array([[1, 0, 0, 0, 0, 0, 0, 0],
+ [0, 1, 0, 0, 0, 0, 0, 0],
+ [0, 0, 0, 0, 0, 0, 1, 0],
+ [0, 0, 0, 0, 0, 0, 0, 1],
+ [0, 0, 0, 0, 1, 0, 0, 0],
+ [0, 0, 0, 0, 0, 1, 0, 0],
+ [0, 0, 1, 0, 0, 0, 0, 0],
+ [0, 0, 0, 1, 0, 0, 0, 0]])
+
Source code in opensquirrel\utils\matrix_expander.py
+ 143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 |
|
+ get_reduced_ket(ket, qubits)
+
+
+
+
+ Given a quantum ket represented by its corresponding base-10 integer, this computes the reduced ket
+where only the given qubits appear, in order.
+Roughly equivalent to the pext
assembly instruction (bits extraction).
Parameters:
+Name | +Type | +Description | +Default | +
---|---|---|---|
ket |
+
+ int
+ |
+
+
+
+ A quantum ket, represented by its corresponding non-negative integer. + By convention, qubit #0 corresponds to the least significant bit. + |
+ + required + | +
qubits |
+
+ List[Qubit]
+ |
+
+
+
+ The indices of the qubits to extract. Order matters. + |
+ + required + | +
Returns:
+Type | +Description | +
---|---|
+ int
+ |
+
+
+
+ The non-negative integer corresponding to the reduced ket. + |
+
Examples:
+>>> get_reduced_ket(1, [Qubit(0)]) # 0b01
+1
+>>> get_reduced_ket(1111, [Qubit(2)]) # 0b01
+1
+>>> get_reduced_ket(1111, [Qubit(5)]) # 0b0
+0
+>>> get_reduced_ket(1111, [Qubit(2), Qubit(5)]) # 0b01
+1
+>>> get_reduced_ket(101, [Qubit(1), Qubit(0)]) # 0b10
+2
+>>> get_reduced_ket(101, [Qubit(0), Qubit(1)]) # 0b01
+1
+
Source code in opensquirrel\utils\matrix_expander.py
+ 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 |
|