11
$\begingroup$

In qiskit, I can transpile a given circuit into a some predefined gate set as follows (just an example)

from qiskit import QuantumCircuit from qiskit.compiler import transpile from qiskit.circuit.random import random_circuit basis_gates = ['id', 'u3', 'cx'] qc = random_circuit(3, 1, seed=0) qc_trans = transpile(qc, basis_gates=basis_gates) 

I have several related questions.

  1. Where can I find an exhaustive list of operators allowed as basis_gates?
  2. For any operator label from the list of allowed basis gates, how can I find the precise meaning of the corresponding gate, say as a matrix representation?
  3. Most importantly, can I add my own custom gates to use as basis gates? Can I add parametric gates? For examples as far as I can tell qiskit standard tools include Rxz and Ryz gates but no Rxy gate. Can I make one?

Example of a (trivial) transpilation into custom gate set failing

from qiskit import QuantumCircuit from qiskit.compiler import transpile qc = QuantumCircuit(2, name='mycx') qc.cx(0, 1) mycx = qc.to_gate() qc = QuantumCircuit(2) qc.cx(0, 1) transpile(qc, basis_gates=['id','mycx']) 

gives me a TranspileError.

$\endgroup$
4
  • $\begingroup$ in your mycx example, you probably mean qc.append(mycx, [0, 1]) instead of qc.cx(0, 1). With that change, it works. $\endgroup$ Commented Jun 8, 2021 at 11:39
  • $\begingroup$ @luciano Nono, the whole point is that although cx is essential the same as mycx I would like the transpiler to find that out. More generally, I would like to get the transpilation into any custom universal gate set. $\endgroup$ Commented Jun 8, 2021 at 11:40
  • $\begingroup$ I added the section Your custom gate as basis target of a circuit that is not using it as part of my answer. Let me know if that makes it. $\endgroup$ Commented Jun 9, 2021 at 8:18
  • $\begingroup$ Also, check this youtube video: Unitary matrix to 1Q, 2QGates $\endgroup$ Commented Aug 13, 2022 at 8:15

2 Answers 2

13
$\begingroup$

The Qiskit standard gate list

You can find the full list of Qiskit standard gates in the module qiskit.circuit.library.standard_gates (documentation).

The matrix representation of a standard gate

For each gate, you can see its matrix representation with the to_matrix method. For example:

from qiskit.circuit.library import standard_gates standard_gates.HGate().to_matrix() 
array([[ 0.70710678+0.j, 0.70710678+0.j], [ 0.70710678+0.j, -0.70710678+0.j]]) 

Or, its latex representation:

from qiskit.visualization import array_to_latex array_to_latex(standard_gates.HGate().to_matrix()) 

matrix output in latex

Creating your own custom gate

You can create your own gates from a circuit. For example:

from qiskit import QuantumCircuit custom_circuit = QuantumCircuit(2, name='bell') custom_circuit.h(0) custom_circuit.cx(0, 1) custom_gate = custom_circuit.to_gate() 

You can create a circuit using that custom gate:

circuit = QuantumCircuit(3) circuit.h(0) circuit.append(custom_gate, [0,1]) circuit.cx(1, 2) circuit.draw() 
 ┌───┐┌───────┐ q_0: ┤ H ├┤0 ├───── └───┘│ bell │ q_1: ─────┤1 ├──■── └───────┘┌─┴─┐ q_2: ──────────────┤ X ├ └───┘ 

Telling the transpiler not to decompose your custom gate

Following the previous example, you can transpile that circuit using the custom gate name in the target basis list:

from qiskit.compiler import transpile basis_gates = ['bell', 'u3', 'cx'] qc_trans = transpile(circuit, basis_gates=basis_gates) qc_trans.draw() 
 ┌─────────────┐┌───────┐ q_0: ┤ U3(π/2,0,π) ├┤0 ├───── └─────────────┘│ bell │ q_1: ───────────────┤1 ├──■── └───────┘┌─┴─┐ q_2: ────────────────────────┤ X ├ └───┘ 

Your custom gate as basis target of a circuit that is not using it

You can basis-target your own custom in some cases. That requires to extend the equivalence library. Following your mycx example:

  1. Create a circuit definition with your custom gate
mycx = QuantumCircuit(2, name='mycx') mycx.cx(0, 1) mycx_def = QuantumCircuit(2) mycx_def.append(mycx.to_gate(), [0, 1]) 
  1. Add an equivalence to the library where a gate (CXGate in this case) is equivalent to that definition.
StandardEquivalenceLibrary.add_equivalence(CXGate(), mycx_def) 
  1. Create a circuit that uses the domain gate (CXGate in this case).
from qiskit.compiler import transpile qc = QuantumCircuit(3) qc.h(0) qc.cx(0, 1) qc.cx(1, 2) 
  1. Transpile using the parameter translation_method='translator'. This will tell the transpiler to use the equivalence library for basis translation. In the basis_gate parameter you can refer to your custom gate name (mycx in this case):
result = transpile(qc, basis_gates=['mycx', 'u3'], translation_method='translator') result.draw() 
 ┌─────────────┐┌───────┐ q_0: ┤ U3(π/2,0,π) ├┤0 ├───────── └─────────────┘│ mycx │┌───────┐ q_1: ───────────────┤1 ├┤0 ├ └───────┘│ mycx │ q_2: ────────────────────────┤1 ├ └───────┘ 
$\endgroup$
8
  • $\begingroup$ Hi, thanks a lot for your answer! I have several follow up questions though. (1) If I just have a label from basis_gates list like 'u3' or 'cx', can I do something like Gate.from_label('cx') instead of looking up the documentation to get the gate? $\endgroup$ Commented Jun 8, 2021 at 11:11
  • $\begingroup$ (2) Your example of transpilation is a bit trivial because you use the custom 'bell' gate both in the original circuit and in the transpiled circuit. In a more practical situation the transpilation seems to fail. Please see updated question. $\endgroup$ Commented Jun 8, 2021 at 11:19
  • $\begingroup$ It is not possible to make a from_label. But it looks like a great feature request candidate: github.com/Qiskit/qiskit-terra/issues/… $\endgroup$ Commented Jun 8, 2021 at 11:29
  • $\begingroup$ Your mycx example fails because qc includes cx which is not in the basis. (and you probably forgot to append mycx to qc? $\endgroup$ Commented Jun 8, 2021 at 11:31
  • $\begingroup$ Thanks a lot for further elaboration! Still, it seems that we have different goals in mind. Ideally, I would like to transpile an arbitrary circuit into any custom gate set which is universal. Theorems like Solovay-Kitaev's guarantee that this is possible. Perhaps I am interested whether there is some general-purpose algorithm under the hood in qiskit that does that. From your new amendment I gather that I need to set the rules for decomposing into my custom gate set by hands. So I would guess that current qiskit traspiler can only target gates native to IBM machines? $\endgroup$ Commented Jun 9, 2021 at 8:34
2
$\begingroup$

You can use BQSKit to accomplish this very easily. BQSKit is a powerful and portable quantum compiler/transpiler. You will need to calculate the unitary of your gate and you can just plug that into BQSKit.

You can accomplish this with the following:

from bqskit import compile, MachineModel, Circuit from bqskit.ir.gates import IdentityGate, ConstantUnitaryGate mycx = ConstantUnitaryGate([...]) # Fill in unitary here model = MachineModel(gate_set={mycx, IdentityGate(1)}) output_circuit = compile(circuit, model) 
$\endgroup$

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.