Skip to content

[FEATURE] Update the depth calculation to include branching operations with classical registers #53

@TheGupta2012

Description

@TheGupta2012

Feature Description

pyqasm: 0.3.2
qiskit: 1.2.0
qiskit-qasm3-import: 0.5.1

Quantum programs with branching conditions containing classical registers should be considered for depth calculations. For example, the following circuit -

In [1]: from qiskit.qasm3 import loads

In [2]: qasm_str = """
   ...: OPENQASM 3.0;
   ...: include "stdgates.inc";
   ...: qreg q[3];
   ...: creg c[3];
   ...: measure q[0] -> c[0];
   ...: cx q[0], q[1];
   ...: measure q[0] -> c[1];
   ...: measure q[0] -> c[2];
   ...: if(c[2]) { h q[2]; }
   ...: """

In [3]: qc = loads(qasm_str)

In [4]: qc.draw(cregbundle = False)
Out[4]: 
     ┌─┐     ┌─┐┌─┐                       
q_0: ┤M├──■──┤M├┤M├───────────────────────
     └╥┘┌─┴─┐└╥┘└╥┘                       
q_1: ─╫─┤ X ├─╫──╫────────────────────────
      ║ └───┘ ║  ║ ┌────── ┌───┐ ───────┐ 
q_2: ─╫───────╫──╫─┤ If-0HEnd-0 ├─
      ║       ║  ║ └──╥─── └───┘ ───────┘ 
c_0: ═╩═══════╬══╬════╬═══════════════════
              ║  ║    ║                   
c_1: ═════════╩══╬════╬═══════════════════
                 ║    ║                   
c_2: ════════════╩════■═══════════════════
                                          

In [5]: qc.depth()
Out[5]: 5

has a depth of 5 whereas pyqasm gives a depth of 4 -

In [7]: import pyqasm

In [8]: qasm_str = """
   ...: OPENQASM 3.0;
   ...: include "stdgates.inc";
   ...: qreg q[3];
   ...: creg c[3];
   ...: measure q[0] -> c[0];
   ...: cx q[0], q[1];
   ...: measure q[0] -> c[1];
   ...: measure q[0] -> c[2];
   ...: if(c[2]) { h q[2]; }
   ...: """

In [9]: pyqasm.loads(qasm_str).depth()
Out[9]: 4

This is because the classical register depth is not considered during the calculation of qubit depths inside the if block. The depth of c_2 is 4 when it is used to condition the H gate on q_2.

Implementation (Optional)

  • While unrolling the branching conditions, we look at whether the condition contains a set of classical register bits or not. We need to update the depth of all these classical bits to the max depth of this set of bits, eg. -
In [75]: qc.draw(cregbundle=False)
Out[75]:
     ┌─┐     ┌─┐┌─┐
q_0: ┤M├──■──┤M├┤M├─────
     └╥┘┌─┴─┐└╥┘└╥┘
q_1: ─╫─┤ X ├─╫──╫──────
      ║ └───┘ ║  ║ ┌───┐
q_2: ─╫───────╫──╫─┤ H ├
      ║       ║  ║ └─╥─┘
c_0: ═╩═══════╬══╬═══╬══
              ║  ║   ║
c_1: ═════════╩══╬═══╬══
                 ║   ║
c_2: ════════════╩═══■══

c_3: ═══════════════════


In [76]: qc.depth()
Out[76]: 5

Here, if c_0, c_1 and c_2 were used in a branching statement, the depth of each bit would be set to 4 as max depth of bits i.e. c_2 is 4. In above example, since c_2 is used for the classically conditioned H gate, the depth of the circuit is supposed to be 5 but is coming out as 4 with pyqasm -

In [82]: import pyqasm

In [83]: qasm_str = 'OPENQASM 3.0;\ninclude "stdgates.inc";\nbit[4] c;\nqubit[3] q;\nc[0] = m
    ...: easure q[0];\ncx q[0], q[1];\nc[1] = measure q[0];\nc[2] = measure q[0];\nif (c[2])
    ...: {\n  h q[2];\n}\n'

In [84]: pyqasm.load(qasm_str).depth()
Out[84]: 4
  • It is not entirely clear how this "max depth of involved classical bits" will be trickled down to the qubits of the if block. A brute force approach is used inside the qbraid sdk's depth function but might not work for a recursive approach used in QasmVisitor.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or requestqasm3Related to openqasm3unitary-hackIssues for the Unitary Hack

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions