fix an issue of while_loop at the tail of a circuit (#1600)

This commit is contained in:
Hiroshi Horii 2022-09-15 02:37:34 +09:00 committed by GitHub
parent e3e5a28e2b
commit 44b8fbef5d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 24 additions and 1 deletions

View File

@ -0,0 +1,7 @@
---
fixes:
- |
Fixes an issue when while_loop is the tail of QuantumCircuit. while_loop
is translated to jump and mark instructions. However, if a while_loop is
at the end of a circuit, its mark instruction is truncated wrongly. This
fix corrects the truncation algorithm to always remain mark instructions.

View File

@ -269,6 +269,8 @@ void Circuit::set_params(bool truncation) {
for (size_t i = 0; i < size; ++ i) {
const size_t rpos = size - i - 1;
const auto& op = ops[rpos];
if (op.type == OpType::mark && last_ancestor_pos == 0)
last_ancestor_pos = rpos;
if (!truncation || check_result_ancestor(op, ancestor_qubits)) {
add_op_metadata(op);
ancestor[rpos] = true;
@ -391,7 +393,7 @@ void Circuit::set_params(bool truncation) {
head_end = last_ancestor_pos + 1;
}
for (size_t pos = 0; pos < head_end; ++pos) {
if (ops_to_remove && !ancestor[pos]) {
if (ops_to_remove && !ancestor[pos] && ops[pos].type != OpType::mark && ops[pos].type != OpType::jump) {
// Skip if not ancestor
continue;
}

View File

@ -514,3 +514,17 @@ class TestControlFlow(SimulatorTestCase):
counts = result.get_counts()
self.assertEqual(len(counts), 1)
self.assertIn('011', counts)
@data('statevector', 'density_matrix', 'matrix_product_state')
def test_while_loop_last(self, method):
backend = self.backend(method=method)
circ = QuantumCircuit(1, 1)
circ.h(0)
circ.measure(0, 0)
with circ.while_loop((circ.clbits[0], True)):
circ.h(0)
circ.measure(0, 0)
result = backend.run(circ, method=method).result()
self.assertSuccess(result)