Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Invalid SliceIterator on Circuit with mid measurement #1357

Closed
lmondada opened this issue Apr 17, 2024 · 3 comments · Fixed by #1716
Closed

Invalid SliceIterator on Circuit with mid measurement #1357

lmondada opened this issue Apr 17, 2024 · 3 comments · Fixed by #1716
Assignees
Labels
bug Something isn't working

Comments

@lmondada
Copy link
Contributor

After investigating #1324, it seems the bug is not in SquashRzPhasedX, but in the command iteration utility. In fact, consider the following circuit:

  Circuit c(2, 1);
  c.add_op<unsigned>(OpType::CZ, {0, 1});
  auto meas = c.add_measure(1, 0);

  auto cl_input = c.c_inputs()[0];
  EdgeVec preds;
  preds.push_back(c.get_nth_out_edge(cl_input, 0));
  preds.push_back(c.get_nth_out_edge(meas, 0));
  auto ptr =
      std::make_shared<Conditional>(get_op_ptr(OpType::Rz, 0.1, 1), 1, 0);
  auto new_v = c.add_vertex(ptr);
  op_signature_t sigs;
  sigs.push_back(EdgeType::Boolean);
  sigs.push_back(EdgeType::Quantum);
  c.rewire(new_v, preds, sigs);

This circuit definition is slightly awkward, as I don't think there is any add_op-type calls I can use to build the circuit as needed. The "trick" here is that a measurement is performed and a quantum gate is then added on the measured qubit post-measurement. However, the gate is classically controlled on the classical value of the classical bit before the measurement. It is a valid DAG, but there is no linear order of the "measure" and "add_conditional" operations that would yield this graph. As far as I can tell, though, it is valid. It looks as follows:

image

The following assertion then fails:

  auto slice_it = c.slice_begin();
  assert(slice_it.finished() || (*++slice_it).size() > 0);

AFAIK this is an invalid state for the iterator to be in.

Full MWE:

#include <iostream>
#include <tkassert/Assert.hpp>
#include <tket/Circuit/Circuit.hpp>

#include "tket/Circuit/DAGDefs.hpp"
#include "tket/Gate/OpPtrFunctions.hpp"
#include "tket/OpType/EdgeType.hpp"
#include "tket/Transformations/BasicOptimisation.hpp"
#include "tket/Transformations/Decomposition.hpp"

using namespace tket;

int main() {
  Circuit c(2, 1);
  c.add_op<unsigned>(OpType::CZ, {0, 1});
  auto meas = c.add_measure(1, 0);

  auto cl_input = c.c_inputs()[0];
  EdgeVec preds;
  preds.push_back(c.get_nth_out_edge(cl_input, 0));
  preds.push_back(c.get_nth_out_edge(meas, 0));
  auto ptr =
      std::make_shared<Conditional>(get_op_ptr(OpType::Rz, 0.1, 1), 1, 0);
  auto new_v = c.add_vertex(ptr);
  op_signature_t sigs;
  sigs.push_back(EdgeType::Boolean);
  sigs.push_back(EdgeType::Quantum);
  c.rewire(new_v, preds, sigs);

  auto slice_it = c.slice_begin();
  TKET_ASSERT(slice_it.finished() || (*++slice_it).size() > 0);
  return 0;
}
@lmondada lmondada added the bug Something isn't working label Apr 17, 2024
@cqc-alec
Copy link
Collaborator

I'm not sure what to conclude here. It looks valid as a DAG but not as a Circuit. What should be the output of c.get_commands()? The problem is that conditional gates can only be conditioned on bit values as they are at the time of gate application -- not on previous values.

I don't think compilation passes should end up with DAGs like this.

For reference, the SquashRzPhasedX pass transforms this circuit:
Screenshot from 2024-04-18 10-51-32
into this:
Screenshot from 2024-04-18 10-52-03
which has the same issue.

@cqc-alec
Copy link
Collaborator

I think the unwritten rule we are violating is that a Boolean wire must be the only path in the DAG from its source to its target node.

Copy link

This issue has been automatically marked as stale.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants