Skip to content

Conversation

kdk
Copy link
Member

@kdk kdk commented Dec 9, 2020

Summary

Following #5486 , updates DAGCircuit and QuantumCircuit classes to support optional registers, and to prefer inspecting bits over registers where possible.

Details and comments

on-hold until #5486 merges.

Commits for just this PR (without #5486 ): https://github.com/Qiskit/qiskit-terra/pull/5498/files/45ba1d598141b90818c53abaadf1d64a80102e8b..d13ef0e35946d20facf569f2eadd65a93f678174

@kdk kdk added on hold Can not fix yet optional-registers labels Dec 9, 2020
@kdk kdk added this to the 0.17 milestone Dec 9, 2020
@kdk kdk force-pushed the quantumcircuit-optional-registers-circuit-internals branch 2 times, most recently from 060ffbb to d13ef0e Compare December 11, 2020 22:55
@kdk kdk force-pushed the quantumcircuit-optional-registers-circuit-internals branch 2 times, most recently from acc066e to 82897ed Compare January 20, 2021 21:58
@kdk kdk force-pushed the quantumcircuit-optional-registers-circuit-internals branch from 82897ed to 2eab8aa Compare February 17, 2021 18:36
@mtreinish mtreinish self-assigned this Feb 17, 2021
@kdk kdk force-pushed the quantumcircuit-optional-registers-circuit-internals branch from 2eab8aa to 2e1d399 Compare February 17, 2021 23:58
@kdk kdk removed the on hold Can not fix yet label Feb 18, 2021
Copy link
Member

@mtreinish mtreinish left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This LGTM, just a few comments and questions inline

@@ -310,8 +314,7 @@ def _add_wire(self, wire):
self.output_map[wire] = outp_node
self._multi_graph.add_edge(inp_node._node_id,
outp_node._node_id,
{'name': wire_name,
'wire': wire})
{'wire': wire})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think it would make sense to drop the dict wrapper here and just attach the bit/wire on the edge directly? We'd probably have to change some access patters from edge['wire'] to edge not sure how much that is used.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good idea, it seems like only a handful of places check this property, so it seems a good time to remove the unneeded dict.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added in 664485e .

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After starting Qiskit/rustworkx#252 I expect it was originally a dict because networkx only lets you weight edges with a dict of attributes instead of an object. After we switched to retworkx there wasn't really a reason to change it until now.

for creg in target_cregs
if wire_map[bit] in creg)
except StopIteration:
raise DAGCircuitError('Did not find creg containing '
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be worth updating the docstring to add this error case under the DAGCircuitError raise section. Something like, "also when the specified condition is not present in a classical register"

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added in 686ed2c .

# Raise if wire_map maps condition creg on to more than one
# creg in target DAG.
raise DAGCircuitError('wire_map maps conditional '
'register onto more than one creg.')

if 2**(bit.index) & cond_val:
new_cond_val += 2**(wire_map[bit].index)
if 2**(cond_creg[:].index(bit)) & cond_val:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the [:] just there to workaround around a Register not being a list and not having an index method?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's right. (Alternately, we could consider building the bit-> index dict like we do elsewhere.)

Comment on lines +540 to +541
carg1 = [node1.cargs[i] for i in range(0, len(node1.cargs))]
carg2 = [node2.cargs[i] for i in range(0, len(node2.cargs))]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow, that's surprising nobody caught that we were putting qubits there until now.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like you'd hit this only if you were looking to run TemplateOptimization on a circuit with more than one qreg (but if you did, you'd hit it right away). Might be an edge case no one had run into yet, since its fairly new, and not in the preset pass managers.

@@ -102,27 +102,41 @@ def __str__(self):
return str(id(self))

@staticmethod
def semantic_eq(node1, node2):
def semantic_eq(node1, node2, bit_indices1, bit_indices2):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a bit concerned about this change from a backwards compat and interop PoV. Like someone could have been using semantic eq to compare dag nodes outside of DAGCircuit.__eq__ before right and this will now break them? Maybe making them optional and just having a fallback to node1_qargs = node1._qargs if it's not specified.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense. I'll add that (with a deprecation warning).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added in 0dc3d7a .

@@ -0,0 +1,6 @@
---
other:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking this might be an upgrade note instead, but I guess it is kind of an edge case. It's unlikely that people are depending on the name field on the edge dict of a DAGCircuit

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, moved in 664485e .

@mtreinish
Copy link
Member

The other thing I forgot to ask in the earlier comments was what DAGDependency, there aren't any other changes needed there? It doesn't use wires on the graph like DAGCircuit does, but I thought it tracked the wires in the object (and per node)

@kdk
Copy link
Member Author

kdk commented Feb 22, 2021

The other thing I forgot to ask in the earlier comments was what DAGDependency, there aren't any other changes needed there? It doesn't use wires on the graph like DAGCircuit does, but I thought it tracked the wires in the object (and per node)

Appears not to be, though I'm not the most familiar with the code here. The only references I found to the wires/qargs was in add_op_node and _does_commute, but its possible I missed cases. (Also, maybe DAGDependency should be updated to have add_*bits methods added as was done for DAGCircuit in #5486 .)

kdk added 7 commits February 23, 2021 15:25
Updates DAGCircuit._check_edgemap_registers:
  - Removes unused valregs and valreg arguments and associated code.
  - Renames edge_map and keyregs arguments to inbound_wires and
  inbound_regs. Removes need for proxy register map.
  - Renames several variables to match their outer context in
  DAGCircuit.substitute_node_with_dag.
@kdk kdk force-pushed the quantumcircuit-optional-registers-circuit-internals branch from 2e1d399 to 3a306da Compare February 23, 2021 20:37
Copy link
Member

@mtreinish mtreinish left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM< thanks for updating it. I think this is ready to go now.

Comment on lines +350 to +351
raise DAGCircuitError("(qu)bit %s not found in %s" %
(wire, amap))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this error ever got raised to the user it would make no sense. Not that it made much sense before. Being an internal function it should hopefully only come up during development and not be a big deal.

@mergify mergify bot merged commit a026b62 into Qiskit:master Feb 24, 2021
@kdk kdk added the Changelog: None Do not include in changelog label Mar 31, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Changelog: None Do not include in changelog optional-registers
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants