Fix depth calculation for external gates#198
Conversation
src/pyqasm/modules/base.py
Outdated
|
|
||
| # Unroll using any external gates that have been recorded for this | ||
| # module | ||
| qasm_module.unroll(external_gates = self._external_gates) |
There was a problem hiding this comment.
Note: the design of this solution has been greatly influenced by this internal call: even though unroll may be called externally with the external_gates kwarg defined, internally here it has always been called without. Imho this can be problematic, hence the current approach that is being proposed.
There was a problem hiding this comment.
I guess external_gates is the only kwarg affecting the depth calculation so it is okay to use that here.
Codecov ReportAll modified and coverable lines are covered by tests ✅ 📢 Thoughts on this report? Let us know! |
src/pyqasm/visitor.py
Outdated
| @@ -760,12 +761,13 @@ def _update_qubit_depth_for_gate( | |||
| qubit_node.num_gates += 1 | |||
There was a problem hiding this comment.
Say we have the following program-
OPENQASM 3.0;
include "stdgates.inc";
gate my_gate() q {
h q;
x q;
}
qubit[2] q;
my_gate q[0];According to the above logic, we shall have num_gates for qubit 0 as 3 whereas its depth would be 1 -
In [17]: import pyqasm
In [18]: qasm_str = """
...: OPENQASM 3.0;
...: include "stdgates.inc";
...: gate my_gate() q {
...: h q;
...: x q;
...: }
...: qubit[2] q;
...: my_gate q[0];"""
In [19]: mod = pyqasm.loads(qasm_str)
In [20]: mod.unroll(external_gates = ['my_gate'])
In [21]: mod._qubit_depths
Out[21]:
{('q',
0): QubitDepthNode(reg_name='q', reg_index=0, depth=1, num_resets=0, num_measurements=0, num_gates=3, num_barriers=0),
('q',
1): QubitDepthNode(reg_name='q', reg_index=1, depth=0, num_resets=0, num_measurements=0, num_gates=0, num_barriers=0)}This is happening because we update the num_gates both inside the two basic gates h and x, and while exiting the handling of the external gate itself! This property is used in the printer but the regression isn't detected as we don't have a visualization test with external gates.
Ideally, the check for self._recording_depth should be moved over the whole gate and depth update logic
src/pyqasm/visitor.py
Outdated
| self._unroll_barriers: bool = unroll_barriers | ||
| self._curr_scope: int = 0 | ||
| self._label_scope_level: dict[int, set] = {self._curr_scope: set()} | ||
| self._recording_depth = True |
There was a problem hiding this comment.
Let's name this to self._recording_ext_gate_depth as recording_depth sounds very general.
Then, True will mean we are inside the external gate and False otherwise.
Essentially, we just flip your current logic
TheGupta2012
left a comment
There was a problem hiding this comment.
Hi @antalszava thanks for working on this!
I've given some suggestions but overall the code looks good, will be happy to merge once they are addressed
Co-authored-by: Harshit Gupta <harshit.11235@gmail.com>
|
Hi @TheGupta2012, thank you! I have made updates as per the suggestions. |
Summary of changes
This PR fixes how the depth of a QASM module is calculated when calling the
depthmethod.With the changes in this PR, a QASM module stores external gates that have been defined for it. At the moment, the main way to define external gates on a module is to pass the
external_gateskeyword argument to theunrollmethod. Calling the sameunrollmethod with no such arguments being passed flushes the external gates of the module.Storing such external gates on the module level helps the depth calculation: any external gates of the module contribute once to the overall depth of the module, instead of the definition of the external gate being considered.
Closes #77.