qiskit-ibm-runtime
qiskit-ibm-runtime copied to clipboard
Cannot transpile dynamic circuits with simulator backends
Information
- qiskit-ibm-provider version: 0.6.3
- Python version:
- Operating system:
What is the current behavior?
Transpiling a dynamic circuit works with a real backend:
from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister, transpile
qr = QuantumRegister(2)
cr = ClassicalRegister(2)
qc_if_else = QuantumCircuit(qr, cr)
qc_if_else.h(0)
qc_if_else.measure(qr[0], cr[1])
with qc_if_else.if_test((cr[0], True)) as else_:
qc_if_else.x(qr[0])
with else_:
qc_if_else.x(qr[1])
qc_if_else.measure(qr[0], cr[1])
from qiskit_ibm_provider import IBMProvider
provider = IBMProvider()
backend = provider.get_backend("ibm_sherbrooke")
qc_if_else_transpiled = transpile(qc_if_else, backend)
But not with ibmq_qasm_simulator
:
sim_backend = provider.get_backend("ibmq_qasm_simulator")
qc_if_else_transpiled = transpile(qc_if_else, sim_backend)
TranspilerError: "The control-flow construct 'if_else' is not supported by the backend."
It also doesn't work with any backend from qiskit-ibm-runtime
Steps to reproduce the problem
See above.
What is the expected behavior?
Transpilation should work.
Suggested solutions
I think this was fixed when we did the ISA circuit change, but someone should test it.
Getting the same error with ibmq_qasm_simulator: TranspilerError: "The control-flow construct 'if_else' is not supported by the backend."
We should check if the backend config file has those instructions. If not, then IQP needs to update them
Can confirm that the ibmq_qasm_simulator
configuration does not have any supported instructions:
Also left a comment in sw-api-iqp issue 1252
{'_data': {'allow_q_object': True},
'backend_name': 'ibmq_qasm_simulator',
'backend_version': '0.1.547',
'n_qubits': 32,
'basis_gates': ['u1',
'u2',
'u3',
'u',
'p',
'r',
'rx',
'ry',
'rz',
'id',
'x',
'y',
'z',
'h',
's',
'sdg',
'sx',
't',
'tdg',
'swap',
'cx',
'cy',
'cz',
'csx',
'cp',
'cu1',
'cu2',
'cu3',
'rxx',
'ryy',
'rzz',
'rzx',
'ccx',
'cswap',
'mcx',
'mcy',
'mcz',
'mcsx',
'mcp',
'mcu1',
'mcu2',
'mcu3',
'mcrx',
'mcry',
'mcrz',
'mcr',
'mcswap',
'unitary',
'diagonal',
'multiplexer',
'initialize',
'kraus',
'roerror',
'delay'],
'gates': [GateConfig(u1, ['lam'], gate u1(lam) q { U(0,0,lam) q; }, True, 'Single-qubit gate [[1, 0], [0, exp(1j*lam)]]'),
GateConfig(u2, ['phi', 'lam'], gate u2(phi,lam) q { U(pi/2,phi,lam) q; }, True, 'Single-qubit gate [[1, -exp(1j*lam)], [exp(1j*phi), exp(1j*(phi+lam))]]/sqrt(2)'),
GateConfig(u3, ['theta', 'phi', 'lam'], gate u3(theta,phi,lam) q { U(theta,phi,lam) q; }, True, 'Single-qubit gate with three rotation angles'),
GateConfig(u, ['theta', 'phi', 'lam'], gate u(theta,phi,lam) q { U(theta,phi,lam) q; }, True, 'Single-qubit gate with three rotation angles'),
GateConfig(p, ['lam'], gate p(lam) q { U(0,0,lam) q; }, True, 'Single-qubit rotation about the Z axis'),
GateConfig(r, ['theta', 'phi'], gate r(theta,phi) q { U(theta,phi-pi/2,-phi+pi/2) q; }, True, 'Rotation around an axis in x-y plane'),
GateConfig(rx, ['theta'], gate rx(theta) q { U(theta,-pi/2,pi/2) q; }, True, 'Rotation around the X axis'),
GateConfig(ry, ['theta'], gate ry(theta) q { U(theta,0,0) q; }, True, 'Rotation around the Y axis'),
GateConfig(rz, ['phi'], gate rz(phi) q { U(0,0,phi) q; }, True, 'Rotation around the Z axis'),
GateConfig(cx, [], gate cx c,t { CX c,t; }, True, 'Two-qubit Controlled-NOT gate'),
GateConfig(cy, [], gate cy a,b { U(0,0,-pi/2) b; CX a,b; U(0,0,pi/2) b; }, True, 'Two-qubit Controlled-Y gate'),
GateConfig(cz, [], gate cz a,b { U(pi/2,0,pi) b; CX a,b; U(pi/2,0,pi) b; }, True, 'Two-qubit Controlled-Z gate'),
GateConfig(csx, [], gate csx a,b { U(pi/2,0,pi) b; CX a,b; U(pi/2,0,pi) b; U(0,0,lam/2) a; CX a,b; U(0,0,-lam/2) b; CX a,b; U(0,0,lam/2) b; U(pi/2,0,pi) b; }, True, 'Two-qubit Controlled Sqrt(X) gate'),
GateConfig(cp, [], gate cp(theta) a,b { U(0,0,theta/2) a; CX a,b; U(0,0,-theta/2) b; CX a,b; U(0,0,theta/2) b; }, True, 'Controlled-Phase gate'),
GateConfig(id, [], gate id a { U(0,0,0) a; }, True, 'Single-qubit identity gate'),
GateConfig(x, [], gate x a { U(pi,0,pi) a; }, True, 'Single-qubit Pauli-X gate'),
GateConfig(y, [], gate y a { U(pi,pi/2,pi/2) a; }, True, 'Single-qubit Pauli-Y gate'),
GateConfig(z, [], gate z a { U(0,0,pi) a; }, True, 'Single-qubit Pauli-Z gate'),
GateConfig(h, [], gate h q { U(pi/2,0,pi) q; }, True, 'Single-qubit Hadamard gate'),
GateConfig(s, [], gate s q { U(0,0,pi/2) q; }, True, 'Single-qubit phase gate'),
GateConfig(sdg, [], gate sdg q { U(0,0,-pi/2) q; }, True, 'Single-qubit adjoint phase gate'),
GateConfig(sx, [], gate sx q { U(pi/2,-pi/2,pi/2) q; }, True, 'Single-qubit Sqrt(X) gate'),
GateConfig(t, [], gate t q { U(0,0,pi/4) q; }, True, 'Single-qubit T gate'),
GateConfig(tdg, [], gate t q { U(0,0,-pi/4) q; }, True, 'Single-qubit adjoint T gate'),
GateConfig(swap, [], TODO, True, 'Two-qubit SWAP gate'),
GateConfig(ccx, [], TODO, True, 'Three-qubit Toffoli gate'),
GateConfig(cswap, [], TODO, True, 'Three-qubit Fredkin (controlled-SWAP) gate'),
GateConfig(unitary, ['matrix'], unitary(matrix) q1, q2,..., True, 'N-qubit unitary gate. The parameter is the N-qubit matrix to apply.'),
GateConfig(diagonal, ['diag_elements'], TODO, True, 'N-qubit diagonal unitary gate. The parameters are the diagonal entries of the N-qubit matrix to apply.'),
GateConfig(initialize, ['vector'], initialize(vector) q1, q2,..., False, 'N-qubit state initialize. Resets qubits then sets statevector to the parameter vector.'),
GateConfig(cu1, ['lam'], gate cu1(lam) a,b { U(0,0,lam/2) a; CX a,b; U(0,0,-lam/2) b; CX a,b; U(0,0,lam/2) b; }, True, 'Two-qubit Controlled-u1 gate'),
GateConfig(cu2, ['phi', 'lam'], TODO, True, 'Two-qubit Controlled-u2 gate'),
GateConfig(cu3, ['theta', 'phi', 'lam'], TODO, True, 'Two-qubit Controlled-u3 gate'),
GateConfig(rxx, ['theta'], gate rxx a,b { U(pi/2,0,pi) a; U(pi/2,0,pi) b; CX a,b; U(0,0,phi) b; CX a,b; U(pi/2,0,pi) b; U(pi/2,0,pi) a; }, True, 'Two-qubit XX-rotation gate'),
GateConfig(ryy, ['theta'], gate ryy a,b { U(pi/2,-pi/2,pi/2) a; U(pi/2,-pi/2,pi/2) b; CX a,b; U(0,0,theta) q; CX a,b; U(-pi/2,-pi/2,pi/2) a; U(-pi/2,-pi/2,pi/2) b; }, True, 'Two-qubit YY-rotation gate'),
GateConfig(rzz, ['theta'], gate rzz a,b { CX a,b; U(0,0,theta) b; CX a,b; }, True, 'Two-qubit ZZ-rotation gate'),
GateConfig(rzx, ['theta'], gate rzx a,b { U(pi/2,0,pi) b; CX a,b; U(0,0,theta) b; CX a,b; U(pi/2,0,pi) b; }, True, 'Two-qubit ZX-rotation gate'),
GateConfig(mcx, [], TODO, True, 'N-qubit multi-controlled-X gate'),
GateConfig(mcy, [], TODO, True, 'N-qubit multi-controlled-Y gate'),
GateConfig(mcz, [], TODO, True, 'N-qubit multi-controlled-Z gate'),
GateConfig(mcsx, [], TODO, True, ''),
GateConfig(mcp, ['lam'], TODO, True, 'Multi-controlled-Phase gate'),
GateConfig(mcu1, ['lam'], TODO, True, 'N-qubit multi-controlled-u1 gate'),
GateConfig(mcu2, ['phi', 'lam'], TODO, True, 'N-qubit multi-controlled-u2 gate'),
GateConfig(mcu3, ['theta', 'phi', 'lam'], TODO, True, 'N-qubit multi-controlled-u3 gate'),
GateConfig(mcrx, ['theta'], TODO, True, 'Multiple-Controlled X rotation gate'),
GateConfig(mcry, ['theta'], TODO, True, 'Multiple-Controlled Y rotation gate'),
GateConfig(mcrz, ['theta'], TODO, True, 'Multiple-Controlled Z rotation gate'),
GateConfig(mcr, [], TODO, True, 'Multiple-Controlled rotation gate'),
GateConfig(mcswap, [], TODO, True, 'N-qubit multi-controlled-SWAP gate'),
GateConfig(multiplexer, ['mat1', 'mat2', '...'], TODO, True, 'N-qubit multi-plexer gate. The input parameters are the gates for each value.'),
GateConfig(kraus, ['mat1', 'mat2', '...'], TODO, True, 'N-qubit Kraus error instruction. The input parameters are the Kraus matrices.'),
GateConfig(delay, [], TODO, True, 'Delay instruction'),
GateConfig(roerror, ['matrix'], TODO, False, 'N-bit classical readout error instruction. The input parameter is the readout error probability matrix.')],
'local': False,
'simulator': True,
'conditional': True,
'open_pulse': False,
'memory': True,
'max_shots': 100000,
'coupling_map': None,
'dynamic_reprate_enabled': False,
'max_experiments': 300,
'online_date': datetime.datetime(2019, 5, 2, 8, 15, tzinfo=tzutc())}