CQCL / pytket-qiskit

pytket-qiskit, extensions for pytket quantum SDK
Apache License 2.0
16 stars 13 forks source link

`AerBackend` fails to run circuits containing `c3z` instructions #368

Closed cqc-alec closed 2 months ago

cqc-alec commented 4 months ago
from pytket.circuit import Circuit, OpType
from pytket.extensions.qiskit.backends.aer import AerBackend

circuit = Circuit(4)
circuit.add_gate(OpType.CnZ, range(4))

backend = AerBackend()
compilation_pass = backend.default_compilation_pass(0)
compilation_pass.apply(circuit)
backend.run_circuit(circuit, n_shots=10)

produces:

AerError: 'unknown instruction: c3z'
yoshi-qc commented 4 months ago

I compared AerBackend()._backend_info.gate_set and Aer.backends()[0].configuration().basis_gates. ~CnZ is included in AerBackend()._backend_info.gate_set but not in Aer.backends()[0].configuration().basis_gates. Does this make the issue?~

yoshi-qc commented 4 months ago

AerBackend()._backend_info.gate_set Output:

{<OpType.Barrier: 8>,
 <OpType.RangePredicate: 17>,
 <OpType.Z: 22>,
 <OpType.X: 23>,
 <OpType.Y: 24>,
 <OpType.S: 25>,
 <OpType.Sdg: 26>,
 <OpType.T: 27>,
 <OpType.Tdg: 28>,
 <OpType.SX: 31>,
 <OpType.SXdg: 32>,
 <OpType.H: 33>,
 <OpType.Rx: 34>,
 <OpType.Ry: 35>,
 <OpType.Rz: 36>,
 <OpType.U3: 37>,
 <OpType.U2: 38>,
 <OpType.U1: 39>,
 <OpType.TK1: 43>,
 <OpType.CX: 45>,
 <OpType.CY: 46>,
 <OpType.CZ: 47>,
 <OpType.CSX: 51>,
 <OpType.CRz: 55>,
 <OpType.CRx: 56>,
 <OpType.CRy: 57>,
 <OpType.CU1: 58>,
 <OpType.CU3: 59>,
 <OpType.CCX: 61>,
 <OpType.SWAP: 62>,
 <OpType.CSWAP: 63>,
 <OpType.noop: 65>,
 <OpType.Measure: 66>,
 <OpType.Reset: 68>,
 <OpType.ECR: 69>,
 <OpType.PhasedX: 71>,
 <OpType.XXPhase: 74>,
 <OpType.YYPhase: 75>,
 <OpType.ZZPhase: 76>,
 <OpType.CnX: 84>,
 <OpType.CnZ: 85>,
 <OpType.Unitary1qBox: 88>,
 <OpType.Unitary2qBox: 89>,
 <OpType.Unitary3qBox: 90>,
 <OpType.StatePreparationBox: 104>,
 <OpType.Conditional: 108>}
yoshi-qc commented 4 months ago

Aer.backends()[0].configuration().basis_gates Output:

['ccx',
 'ccz',
 'cp',
 'crx',
 'cry',
 'crz',
 'cswap',
 'csx',
 'cu',
 'cu1',
 'cu2',
 'cu3',
 'cx',
 'cy',
 'cz',
 'diagonal',
 'ecr',
 'h',
 'id',
 'initialize',
 'mcp',
 'mcphase',
 'mcr',
 'mcrx',
 'mcry',
 'mcrz',
 'mcswap',
 'mcsx',
 'mcu',
 'mcu1',
 'mcu2',
 'mcu3',
 'mcx',
 'mcx_gray',
 'mcy',
 'mcz',
 'multiplexer',
 'p',
 'pauli',
 'r',
 'roerror',
 'rx',
 'rxx',
 'ry',
 'ryy',
 'rz',
 'rzx',
 'rzz',
 's',
 'sdg',
 'swap',
 'sx',
 'sxdg',
 't',
 'tdg',
 'u',
 'u1',
 'u2',
 'u3',
 'unitary',
 'x',
 'y',
 'z',
 'break_loop',
 'continue_loop',
 'delay',
 'for_loop',
 'if_else',
 'kraus',
 'qerror_loc',
 'quantum_channel',
 'reset',
 'roerror',
 'save_amplitudes',
 'save_amplitudes_sq',
 'save_clifford',
 'save_density_matrix',
 'save_expval',
 'save_expval_var',
 'save_matrix_product_state',
 'save_probabilities',
 'save_probabilities_dict',
 'save_stabilizer',
 'save_state',
 'save_statevector',
 'save_statevector_dict',
 'save_superop',
 'save_unitary',
 'set_density_matrix',
 'set_matrix_product_state',
 'set_stabilizer',
 'set_statevector',
 'set_superop',
 'set_unitary',
 'superop',
 'switch_case',
 'while_loop']
yoshi-qc commented 4 months ago

I found 'mcz' is corresponding to OpType.CnZ.

yoshi-qc commented 4 months ago

I think we replace qiskit gates on the L703 and L705 in mcy and mcz (similar to L701). https://github.com/CQCL/pytket-qiskit/blob/94174692d5135a3fd9b55b9a3b99ec53ad342942/pytket/extensions/qiskit/qiskit_convert.py#L703

cqc-alec commented 4 months ago

I think we replace qiskit gates on the L703 and L705 in mcy and mcz (similar to L701).

https://github.com/CQCL/pytket-qiskit/blob/94174692d5135a3fd9b55b9a3b99ec53ad342942/pytket/extensions/qiskit/qiskit_convert.py#L703

Indeed, and the problem is that ZGate().control(3) is converted to a c3z instruction rather than mcz.

CalMacCQ commented 4 months ago

Can you actually create a standalone instance of an MCZ gate in the latest qiskit versions? looking at the docs I can only see MCX.

Seems to have some sort of definition in qiskit-aer

yoshi-qc commented 3 months ago

Can you actually create a standalone instance of an MCZ gate in the latest qiskit versions?

I use qiskit==1.1.1 and qiskit-aer==0.14.2 which are automatically installed when I installed pytket-qiskit==0.53.0. I try Aer.backends()[0].configuration().basis_gates and I can see the gates 'mcx', 'mcy', and 'mcz'.

Seems to have some sort of definition in qiskit-aer

Thanks. This is good to know!

yoshi-qc commented 3 months ago

I found a typo. https://github.com/CQCL/pytket-qiskit/blob/94174692d5135a3fd9b55b9a3b99ec53ad342942/pytket/extensions/qiskit/qiskit_convert.py#L146

Here, should qiskit_gates.CCZGate: OpType.CCZ,

This is reason why the CnY gete works but the CnZ gate doesn't work.

CalMacCQ commented 3 months ago

Here, should qiskit_gates.CCZGate: OpType.CCZ,

There is no CCZ member of OpType in pytket so we need to treat a CCZ as a case of CnZ

yoshi-qc commented 3 months ago

I see. The line 146 is for qiskit_to_tk. Okey, I'll edit L703 and L705.

yoshi-qc commented 3 months ago

As @CalMacCQ has concern about as above, QuantumCircuit does not accept mcz and mcy. So I changed only the gate name with mcz and fixed the bug. https://github.com/CQCL/pytket-qiskit/blob/a18e81e8c2f1578696d0ab0c6fa963e01381bfc0/pytket/extensions/qiskit/qiskit_convert.py#L706

yoshi-qc commented 3 months ago

I made the test function text_mc_gate_on_aer and I made PR but the function seems to be skipped in CI. Do you know why the function is skipped? https://github.com/CQCL/pytket-qiskit/blob/a18e81e8c2f1578696d0ab0c6fa963e01381bfc0/tests/backend_test.py#L1435

cqc-alec commented 3 months ago

I made the test function text_mc_gate_on_aer and I made PR but the function seems to be skipped in CI. Do you know why the function is skipped?

https://github.com/CQCL/pytket-qiskit/blob/a18e81e8c2f1578696d0ab0c6fa963e01381bfc0/tests/backend_test.py#L1435

It's because your test name starts with "text", not "test"!

yoshi-qc commented 3 months ago

It's because your test name starts with "text", not "test"!

Thanks. I confirm that the function is passed if I change the name with "test".

cqc-alec commented 3 months ago

PR here: https://github.com/CQCL/pytket-qiskit/pull/369