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

Add CircuitDag class #759

Merged
merged 9 commits into from
Jul 25, 2018
Merged

Add CircuitDag class #759

merged 9 commits into from
Jul 25, 2018

Conversation

cduck
Copy link
Collaborator

@cduck cduck commented Jul 25, 2018

Resolves #547.

Add networkx as a dependency.

@cduck cduck requested a review from Strilanc July 25, 2018 07:44
@googlebot googlebot added the cla: yes Makes googlebot stop complaining. label Jul 25, 2018
@cduck cduck force-pushed the circuitdag branch 2 times, most recently from 85730d1 to 7105189 Compare July 25, 2018 07:58

T = TypeVar('T')

class Unique(Generic[T]):
Copy link
Contributor

Choose a reason for hiding this comment

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

Add a docstring explaining why this is needed.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done.

TSelf = TypeVar('TSelf', bound='CircuitDagAbc')

class CircuitDagAbc(networkx.DiGraph, metaclass=abc.ABCMeta):
"""A representation of a Circuit as a directed acyclic graph. Subclass
Copy link
Contributor

Choose a reason for hiding this comment

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

Move the second sentence into a separate paragraph.


class CircuitDagAbc(networkx.DiGraph, metaclass=abc.ABCMeta):
"""A representation of a Circuit as a directed acyclic graph. Subclass
CircuitDagAbc and implement can_reorder()."""
Copy link
Contributor

Choose a reason for hiding this comment

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

Explain the goal achieved by subclassing and implementing the method.

super().__init__(incoming_graph_data)
self.device = device

@abc.abstractmethod
Copy link
Contributor

Choose a reason for hiding this comment

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

I think, given that this is a "data structure class", it makes more sense to tell it how to do things by providing constructor arguments rather than via inheritance. For example, the way you use defaultdict is not by subclassing it and implementing a make_value method; you give the constructor a make_value lambda. Do that.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done.

return get_root_node(next(iter(g.nodes)))

def get_next_node(succ):
if len(succ) > 0:
Copy link
Contributor

Choose a reason for hiding this comment

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

Simplify to if len(succ) or if succ.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done.

def get_first_node():
return get_root_node(next(iter(g.nodes)))

def get_next_node(succ):
Copy link
Contributor

Choose a reason for hiding this comment

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

What's the type of succ and the return type?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done.

succ = g.succ[node]
g.remove_node(node)

if len(g.nodes) <= 0:
Copy link
Contributor

Choose a reason for hiding this comment

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

Simplify to if not len(g.nodes) or if not g.nodes if possible.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done.


def get_root_node(some_node):
pred = g.pred
while len(pred[some_node]) > 0:
Copy link
Contributor

Choose a reason for hiding this comment

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

Simplify to if len(pred[some_node]) or if pred[some_node].

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done.

@cduck
Copy link
Collaborator Author

cduck commented Jul 25, 2018

I rewrote many of the docstrings also.

TSelf = TypeVar('TSelf', bound='CircuitDag')


def _default_can_reorder(op1: ops.Operation, op2: ops.Operation) -> bool:
Copy link
Contributor

Choose a reason for hiding this comment

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

Call this "_disjoint_qubits" or similar so that people reading the documentation of the method using this as a default value have a description of what it does instead of how it's used.


Edges of the graph are tuples of nodes. Each edge specifies a required
application order between two operations. The first must be applied before
the second.
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe mention whether the graph is minimalist (e.g. the transitive reduction), maximalist (transitive completion), or just somewhere arbitrary in between.

the second.
"""

default_can_reorder = staticmethod(_default_can_reorder)
Copy link
Contributor

Choose a reason for hiding this comment

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

This is a class attribute so that people can use it for themselves?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes.

device=circuit.device)

@classmethod
def from_ops(cls: Type[TSelf],
Copy link
Contributor

Choose a reason for hiding this comment

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

Is it necessary for these to be class methods anymore, now that there is no inheritance present?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

All done.

Copy link
Contributor

@Strilanc Strilanc left a comment

Choose a reason for hiding this comment

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

LGTM!

@@ -56,13 +56,15 @@ class CircuitDag(networkx.DiGraph):
Edges of the graph are tuples of nodes. Each edge specifies a required
application order between two operations. The first must be applied before
the second.

The graph is maximalist (transitive completion).
Copy link
Contributor

Choose a reason for hiding this comment

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

I know I used it, but I don't think maximalist is a common term.

@cduck cduck merged commit 045487a into quantumlib:master Jul 25, 2018
@cduck cduck deleted the circuitdag branch July 25, 2018 22:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla: yes Makes googlebot stop complaining.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants