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

Refactored and created an abstraction for control values #5362

Merged
merged 17 commits into from
Jul 8, 2022

Conversation

NoureldinYosri
Copy link
Collaborator

Created a concrete implementation that replicates current behaviour.
refactored the code for control_values and abstracted its calls
this is a first step towards implementing more ways to represent control values in order to solve #4512

…n that replicates current behaviour.

refactored the code for control_values and abstracted its calls
this is a first step towards implementing more ways to represent control values in order to solve quantumlib#4512
@NoureldinYosri NoureldinYosri requested review from a team, vtomole and cduck as code owners May 13, 2022 13:59
@CirqBot CirqBot added the size: L 250< lines changed <1000 label May 13, 2022
@NoureldinYosri
Copy link
Collaborator Author

@tanujkhattar

cirq-core/cirq/ops/control_values.py Outdated Show resolved Hide resolved
cirq-core/cirq/ops/control_values.py Outdated Show resolved Hide resolved
cirq-core/cirq/ops/control_values.py Outdated Show resolved Hide resolved
Returns:
An object that represents the cartesian product of the two inputs.
"""
return type(self)(self._internal_representation + other._internal_representation)
Copy link
Collaborator

Choose a reason for hiding this comment

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

This assumes that self._internal_representation and other._internal_representation can be simply added together. But their types are Any, so this need not be true.

Does the current implementation assume that ProductOfSums is the only derived type, and would be special cased later once we add more derived types?

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, this is just for refactoring, this function will be rewritten in a better way once the linked structure is introduced

cirq-core/cirq/ops/control_values.py Outdated Show resolved Hide resolved
cirq-core/cirq/ops/control_values.py Outdated Show resolved Hide resolved
cirq-core/cirq/ops/controlled_gate.py Outdated Show resolved Hide resolved
Copy link
Collaborator

@tanujkhattar tanujkhattar left a comment

Choose a reason for hiding this comment

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

As per our last discussion offline, can we strip down the API to have only what's necessary for this particular PR and add the additional methods in the follow up PR?

@NoureldinYosri
Copy link
Collaborator Author

@tanujkhattar which is why I removed the _iterator function, but all other functions are necessary and are being used/called either directly by functions in controlled_gate, controlled_operation, common_gate or indirectly by other tests.

cirq-core/cirq/ops/control_values.py Outdated Show resolved Hide resolved

@abc.abstractmethod
def identifier(self) -> Tuple[Any]:
"""Returns an identifier from which the object can be rebuilt."""
Copy link
Collaborator

Choose a reason for hiding this comment

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

Improve docstrings, it's not clear to me what it means to "have an identifier from which object can be rebuilt". Does this mean an identifier we can use for serialization / deserialization ?

Also, when would a user use this method? Do we need this to be part of the public API ? Can we just enforce that the class should have a __repr__ defined that satisfies eval(repr(cv)) == cv?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I changed the docstring, this function essentially returns the internal representation, I changed it to be private and I will remove it in the next PR, it's now used in functions in controlled_gate and controlled_operation that require access to the internal representation

cirq-core/cirq/ops/control_values.py Outdated Show resolved Hide resolved
cirq-core/cirq/ops/control_values.py Outdated Show resolved Hide resolved
cirq-core/cirq/ops/control_values.py Outdated Show resolved Hide resolved
cirq-core/cirq/ops/controlled_gate.py Outdated Show resolved Hide resolved
Copy link
Collaborator

@tanujkhattar tanujkhattar left a comment

Choose a reason for hiding this comment

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

Left a bunch of comments for cleanup.

One concern I have is that I don't like the use of the private method control_values._identifier() in controlled gates and operations; because

a) Private methods shouldn't be used outside of the class.
b) it assumes that the underlying _identifier() has a representation which is factorized -- This is true for ProductOfSums implementation but wouldn't be true in the follow-up PR and I guess we'll have to add isinstance checks and special case the behavior in controlled gates and controlled values on different controlled values implementations?

cirq-core/cirq/ops/control_values.py Outdated Show resolved Hide resolved
cirq-core/cirq/ops/control_values.py Outdated Show resolved Hide resolved
pass

def __iter__(self) -> Generator[Tuple[int], None, None]:
def __iter__(self) -> Generator[Tuple[int, ...], None, None]:
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit:

Suggested change
def __iter__(self) -> Generator[Tuple[int, ...], None, None]:
def __iter__(self) -> Iterator[[Tuple[int, ...]]:

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

this is blocked by mypy, it insists on Generator, I originally tried to use Iterator but had to use Generator instead

cirq-core/cirq/ops/control_values.py Outdated Show resolved Hide resolved
cirq-core/cirq/ops/control_values.py Outdated Show resolved Hide resolved
cirq-core/cirq/ops/controlled_gate.py Outdated Show resolved Hide resolved
Comment on lines 25 to 29
"""AbstractControlValues is an abstract immutable data class.

AbstractControlValues defines an API for control values and implements
functions common to all implementations (e.g. comparison).
"""
Copy link
Collaborator

Choose a reason for hiding this comment

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

The docstring should be more detailed. For example:

Suggested change
"""AbstractControlValues is an abstract immutable data class.
AbstractControlValues defines an API for control values and implements
functions common to all implementations (e.g. comparison).
"""
"""Abstract immutable base class that defines the API for control values.
`cirq.ControlledGate` and `cirq.ControlledOperation` are useful to augment existing gates
and operations to have one or more control qubits. For every control qubit, the set of
integer values for which the control should be enabled is represented by
`cirq.AbstractControlValues`.
Implementations of `cirq.AbstractControlValues` can use different internal representations
to store control values, but they should all satisfy the public API defined here.
"""

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

PTAL


@abc.abstractmethod
def _expand(self) -> Iterator[Tuple[Any, ...]]:
"""Returns the control values tracked by the object."""
Copy link
Collaborator

Choose a reason for hiding this comment

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

Please explain more what the "expanded" representation means / contains. Does it depend upon what internal representation the subclasses use? Does every tuple correspond to a "one value per qubit" representation?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

PTAL

cirq-core/cirq/ops/controlled_gate.py Show resolved Hide resolved
Copy link
Collaborator

@tanujkhattar tanujkhattar left a comment

Choose a reason for hiding this comment

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

LGTM % a few final nits, mainly around docstrings. Will be happy to merge once they are resolved.

cirq-core/cirq/ops/control_values.py Outdated Show resolved Hide resolved
cirq-core/cirq/ops/control_values.py Outdated Show resolved Hide resolved
Comment on lines 55 to 57
"""Returns a plain sum of product representation of the values instead
of the (possibly compressed) internal representation.
"""
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: Either convert to a one-liner docstring or follow the guidance for multi-line docstrings described above.

Suggested change
"""Returns a plain sum of product representation of the values instead
of the (possibly compressed) internal representation.
"""
"""Expands the (possibly compressed) internal representation into a sum of products representation."""

cirq-core/cirq/ops/control_values.py Outdated Show resolved Hide resolved
cirq-core/cirq/ops/control_values.py Show resolved Hide resolved
@tanujkhattar tanujkhattar added the automerge Tells CirqBot to sync and merge this PR. (If it's running.) label Jul 8, 2022
@CirqBot CirqBot added the front_of_queue_automerge CirqBot uses this label to indicate (and remember) what's being merged next. label Jul 8, 2022
@CirqBot CirqBot merged commit ea06bfd into quantumlib:master Jul 8, 2022
@CirqBot CirqBot removed automerge Tells CirqBot to sync and merge this PR. (If it's running.) front_of_queue_automerge CirqBot uses this label to indicate (and remember) what's being merged next. labels Jul 8, 2022
rht pushed a commit to rht/Cirq that referenced this pull request May 1, 2023
…5362)

Created a concrete implementation that replicates current behaviour.
refactored the code for control_values and abstracted its calls
this is a first step towards implementing more ways to represent control values in order to solve quantumlib#4512
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
size: L 250< lines changed <1000
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants