I dont think your problem is related with QuantumCircuit
, but with synthesis of such as big MCT. By default, the amount of resulting gates grows very quickly (it looks exponentially), as more qubits are involved
from qiskit import QuantumCircuit
from qiskit import transpile
cxs = []
for controlled in (range(3,20)):
target = 0
control = list(range(target+1,controlled))
qc = QuantumCircuit(num)
qc = QuantumCircuit(num+len(control))
qc.mcx(control, target)
result = transpile(qc, basis_gates=['rx','ry','rz','cx'])
cxs.append(result.count_ops()['cx'])
import matplotlib.pyplot as plt
plt.plot(cxs)
plt.show()
With 20 qubits, the default synthesis results in 800K CXs gates.
However, this default synthesis method uses no ancillas. In the mct documentation, should would notice that there are several "modes". The v-chain
mode is the most efficient in terms of the result, but uses the biggest amount of ancillas. The amount of resulting cnots grows linearly with the amount of controlled qubits:
from qiskit import QuantumCircuit
from qiskit import transpile
cxs = []
for controlled in (range(3,20)):
target = 0
control = list(range(target+1,controlled))
ancilla = list(range(len(control)+1, 2*len(control)-1))
qc = QuantumCircuit(num)
qc = QuantumCircuit(num+len(control)+len(ancilla))
qc.mcx(control, target, ancilla, mode='v-chain') # <-
result = transpile(qc, basis_gates=['rx','ry','rz','cx'])
cxs.append(result.count_ops()['cx'])
import matplotlib.pyplot as plt
plt.plot(cxs)
plt.show()
So, you can create a quantum circuit that considers these ancillas, it would look something like this:
from qiskit import QuantumCircuit
from qiskit import transpile
target = 0 # <- qubit 0 as a target
control = list(range(target+1,60)) # <- controlled qubits
ancilla = list(range(len(control)+1, 2*len(control)-1)) # <- ancilla qubits
print('target', target)
print('control', control)
print('ancilla', ancilla)
qc = QuantumCircuit(num)
qc = QuantumCircuit(num+len(control)+len(ancilla))
qc.mcx(control, target, ancilla, mode='v-chain')
result = transpile(qc, basis_gates=['rx','ry','rz','cx'])
print(result.count_ops())
target 0
control [1, 2, 3, 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]
ancilla [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, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116]
OrderedDict([('rz', 463), ('cx', 348), ('ry', 230), ('rx', 1)])
pytket-qiskit
package then you could convert your qiskitQuantumCircuit
to a pytketCircuit
and try to compile/transpile it with TKET istead. No gaurentee that this would work better but could be worth a try. See -> cqcl.github.io/pytket/manual/… . If this interests you I can provide details on how to do this. $\endgroup$