cda-tum / mqt-core

MQT Core - The Backbone of the Munich Quantum Toolkit
https://mqt.readthedocs.io/projects/core
MIT License
62 stars 31 forks source link

🐛 Circuits with discontiguous qubit registers are not properly exported since v2.7.0 #729

Open burgholzer opened 1 month ago

burgholzer commented 1 month ago

Environment information

Description

When a circuit is stripped of idle qubits in the middle of its range of qubits, the resulting circuit cannot be exported properly because it accesses out-of-bounds memory. Before #690, this was mitigated by modifying the circuit before dumping and explicitly adding back missing qubits. This behaviour has been dropped as it was deemed unintuitive that a circuit dumping method would alter the circuit itself.

Expected behavior

It should be possible to dump circuits that had some of their qubits stripped without modifying the circuits themselves.

It is not 100% clear, what the following code should produce:

QuantumComputation qc(2);
qc.x(1);
qc.stripIdleQubits(true, true);

Options include:

// i 0 1
// o 1
OPENQASM 3.0;
include "stdgates.inc";
qubit q[2];
x q[1];

This is how the code worked before v2.7.0, but this required modifying the circuit by adding back the respective qubit before exporting. One could argue that a circuit that has been stripped of its idle qubits should not contain them anymore. The benefit here is that the gates do not need to be touched.

// i 0
// o 0
OPENQASM 3.0;
include "stdgates.inc";
qubit q[1];
x q;

This method would require the layouts as well as all operations to be updated. On the plus side, it would only require a modification in the function that strips the idle qubits and no updates in the method that dumps the circuits.

How to Reproduce

  QuantumComputation qc(2);
  qc.x(1);
  qc.stripIdleQubits(true, true);

  const auto expected = "// i 1\n"
                        "// o 1\n"
                        "OPENQASM 3.0;\n"
                        "include \"stdgates.inc\";\n"
                        "qubit q[1];\n"
                        "x q;\n";

  EXPECT_EQ(qc.toQASM(), expected);

Or any of the other expected alternatives.

Currently, this yields

// I 1
// o 1
OPENQASM 3.0;
include "stdgates.inc";
qubit[1] q;
x ;

which is obviously invalid.