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

Updated non_parametric ops adjoint method and added test #2133

Merged
merged 32 commits into from Feb 4, 2022

Conversation

Jaybsoni
Copy link
Contributor

Context:
The current adjoint() method implementation for non-parametric operations would lead to a bug in which taking multiple adjoints of the operation do not return the correct result (#1968).

Description of the Change:
Updated the adjoint() method such that instead of initializing a new operation (of the same kind) and applying inv(), it would access the internal boolean attribute op.inverse and flip it.

>>> op = qml.S(wires=0)
>>>
>>>
>>> # OLD: 
>>> print(op)
S(wires=[0])
>>>
>>> print(op.adjoint())
S.inv(wires=[0])
>>>
>>> print(op.adjoint().adjoint())
S.inv(wires=[0])
>>>
>>> 
>>> # New: 
>>> print(op)
S(wires=[0])
>>>
>>> print(op.adjoint())
S.inv(wires=[0])
>>>
>>> print(op.adjoint().adjoint())
S(wires=[0])

@github-actions
Copy link
Contributor

Hello. You may have forgotten to update the changelog!
Please edit doc/releases/changelog-dev.md with:

  • A one-to-two sentence description of the change. You may include a small working example for new features.
  • A link back to this PR.
  • Your name (or GitHub username) in the contributors section.

@codecov
Copy link

codecov bot commented Jan 27, 2022

Codecov Report

❗ No coverage uploaded for pull request base (v0.21.0-rc0@2fbf655). Click here to learn what that means.
The diff coverage is n/a.

Impacted file tree graph

@@              Coverage Diff               @@
##             v0.21.0-rc0    #2133   +/-   ##
==============================================
  Coverage               ?   99.20%           
==============================================
  Files                  ?      230           
  Lines                  ?    17665           
  Branches               ?        0           
==============================================
  Hits                   ?    17525           
  Misses                 ?      140           
  Partials               ?        0           

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 2fbf655...819f2a3. Read the comment docs.

@Jaybsoni
Copy link
Contributor Author

[sc-11983]

Comment on lines +317 to +319
op = S(wires=self.wires)
op.inverse = not self.inverse
return op
Copy link
Member

Choose a reason for hiding this comment

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

minor flyby comment, but I'm curious if the op.inverse = not self.inverse can be included in the qml.adjoint() code, to avoid needing to duplicate it in each gate?

Copy link
Contributor Author

@Jaybsoni Jaybsoni Jan 28, 2022

Choose a reason for hiding this comment

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

My only concern would be that this logic implicitly implies that the underlying object is Unitary (adjoint = inverse). By implementing it into the adjoint() method of the operation class. Even though all operations which inherit from this class override this method, it might still be better to leave it out. But if we just want to include it from the perspective of reducing code redundancy, then yes I should be able to move the logic there 👍🏼

After thinking about this again, I realized all of the operations we work with will be Unitary. I was worried for the case we would be working with Hermitian observables which inherit from the Observable class (which in turn inherits from Operation). But we can deal with this case by simply overriding the adjoint() method in the Observable class directly.

Copy link
Member

Choose a reason for hiding this comment

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

yep, everything (currently) is unitary :)

Copy link
Member

Choose a reason for hiding this comment

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

I suppose my main reason for originally commenting this is less about the abstraction, and more about making the operator class developer friendly.

Currently, op.inverse is an implementation detail which is not publicly documented. Meanwhile, op.adjoint() is part of the public API that developers should define.

We should try and avoid developers needing to know about implementation details to satisfy the API!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@josh146, in moving the logic to the Operation class, I also had to update a bunch of the templates which inherit from Operation but don't have an adjoint method implemented. This could be a good opportunity for coding challenges during the interview process (something like complete the adjoint method for the angle embedding template)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@josh146, after speaking with @albi3ro and the rest of the Core team we concluded that it would be best to go with the simplest option so I am going to revert to simply overwriting the adjoint method in the non-parametric ops since the current change requires updating the adjoint method for all of the templates

Copy link
Member

Choose a reason for hiding this comment

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

no worries! That makes a lot of sense. I believe the templates have already been fixed in op-refactor :)

Jaybsoni and others added 14 commits January 28, 2022 12:55
* add WireCut operator, add qcut package, update docs

* add unit test

* update changelog

* updates

* add tape to graph conversion and unit test

* add unit tests

* add obs to node tests

* restructure qcut module

* add tests for observable and measurement conversion to nodes, update stateprep conversion logic

* fix pylint

* Apply suggestions from code review

Co-authored-by: Tom Bromley <49409390+trbromley@users.noreply.github.com>

* add code review suggestions

* add unit tests

* format

* Apply suggestions from code review

Co-authored-by: Tom Bromley <49409390+trbromley@users.noreply.github.com>

* add review suggestions

* Update pennylane/transforms/qcut.py

Co-authored-by: Tom Bromley <49409390+trbromley@users.noreply.github.com>

Co-authored-by: Tom Bromley <49409390+trbromley@users.noreply.github.com>
* clean changelog-dev

* version bump

* mark current and dev release in the changelog

* Add Qchem v0.21.0 release notes
…2124)

* add WireCut operator, add qcut package, update docs

* add unit test

* update changelog

* updates

* add tape to graph conversion and unit test

* add unit tests

* add obs to node tests

* restructure qcut module

* add tests for observable and measurement conversion to nodes, update stateprep conversion logic

* fix pylint

* add method to replace Wirecut ops with Measure and Prepare ops

* add unit tests

* add unit tests, update changelog

* format

* set measure and prepare node order to be equal (remove 0.5)

* Apply suggestions from code review

Co-authored-by: Tom Bromley <49409390+trbromley@users.noreply.github.com>

* add code review suggestions

* add unit tests

* format

* format

* Apply suggestions from code review

Co-authored-by: Tom Bromley <49409390+trbromley@users.noreply.github.com>

* add review suggestions

* Update pennylane/transforms/qcut.py

Co-authored-by: Tom Bromley <49409390+trbromley@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: Tom Bromley <49409390+trbromley@users.noreply.github.com>

* add review suggestions

* add unit test

* update changelog

* update changelog-0.21.0

* Apply suggestions from code review

Co-authored-by: Tom Bromley <49409390+trbromley@users.noreply.github.com>

* apply review suggestions

* Apply suggestions from code review

Co-authored-by: Tom Bromley <49409390+trbromley@users.noreply.github.com>

Co-authored-by: Tom Bromley <49409390+trbromley@users.noreply.github.com>
Co-authored-by: antalszava <antalszava@gmail.com>
@Jaybsoni Jaybsoni changed the base branch from master to v0.21.0-rc0 February 3, 2022 15:55
@Jaybsoni Jaybsoni changed the base branch from v0.21.0-rc0 to master February 3, 2022 16:01
@Jaybsoni Jaybsoni requested a review from albi3ro February 3, 2022 16:10
@Jaybsoni Jaybsoni changed the base branch from master to v0.21.0-rc0 February 3, 2022 16:13
@@ -406,8 +410,10 @@ def decomposition(wires):
]
return decomp_ops

def adjoint(self):
return SX(wires=self.wires).inv()
def adjoint(self, do_queue=False):
Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder if we should just get rid of the do_queue keyword in the abstract method, as no child operation seem to either accept the do_queue keyword or do anything with it. Shouldn't break anything if we just get rid of it.



@pytest.mark.parametrize("op", all_ops)
@pytest.mark.parametrize("num_adjoint_calls", [1, 2, 3])
Copy link
Contributor

Choose a reason for hiding this comment

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

It might be easier to move this parametrization inside the test. This way is fine, but we could also:

  • take one adjoint
  • validate
  • take second adjoint
  • validate
  • take third adjoint
  • validate

instead of taking it multiple times in a row then validating.

qml.WireCut(wires=0),
]

idempotent_ops = [
Copy link
Contributor

Choose a reason for hiding this comment

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

Might want to leave a note about what "idempotent" means.

@Jaybsoni Jaybsoni requested a review from albi3ro February 3, 2022 20:40
Copy link
Contributor

@albi3ro albi3ro left a comment

Choose a reason for hiding this comment

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

Great to finally have this fixed 🚀

@josh146 josh146 merged commit 2a419f4 into v0.21.0-rc0 Feb 4, 2022
@josh146 josh146 deleted the non_param_op_adjoint branch February 4, 2022 14:03
josh146 added a commit that referenced this pull request Feb 8, 2022
* Run updated version of black on repo (#2140)

* Run updated black on repo

* Also reformat tests

* Dont convert variables to numpy if on interface-specific device (#2136)

* dont unwrap interface devices if diffmethod None

* tests and black

* dont expect warning on test, update changelog

* readability update and test fix

* lint

* Update doc/releases/changelog-dev.md

Co-authored-by: antalszava <antalszava@gmail.com>

* Modify changelog for psi4 bug fix (#2144)

* modify changelog for psi4 bug fix

* move the entry to the QChem changelog

Co-authored-by: Antal Szava <antalszava@gmail.com>

* Add useful error message on empty batch transform (#2139)

* Add error on empty batch transform

When a batch transform collects an empty `params` list, it currently
raises an IndexError. This fix adds a check to raise a useful error
message in cases were there are no trainable parameters and
`all_operations` was not set to True.

Also fix template argument types in docstrings.

* Add test case

* Update changelog-dev.md

Co-authored-by: Romain <rmoyard@gmail.com>
Co-authored-by: antalszava <antalszava@gmail.com>
Co-authored-by: Josh Izaac <josh146@gmail.com>

* Add warning when using `qml.grad`/`qml.jacobian` without any trainable parameters (#2148)

* Add warning for gradients with no trainable params

* Fix tests expecting different warning

* Fix many tests with no trainable params

Catch expected warnings

* Formatting

* Add changelog

* Update doc/releases/changelog-dev.md

* Use quotes instead of backticks

Co-authored-by: antalszava <antalszava@gmail.com>

* changelog typos

* Add `qml.hf.hamiltonian.simplify` to docs (#2162)

* Allow qml.hf.simplify

* dummy change to trigger CI

* PL version bump

* add 0.21.0 file

* Update (#2167)

* create sections

* org

* update

* correct examples

* Num params fix2 (#2135)

* made num_params a class property in all remaining Operations as it indeed is independen of the instance in all currently defined Operations
Changed Operation class to allow sub-classes to define num_params as instance or class property as desired

* made num_params of Identity static

* added a simple test to check that for some operations whose num_params can be a static class property this is actually the case

* updated changelog

* linting

* linting

* take both static and instance num_params property into account when checking number of provided parameters

* black

* Update pennylane/operation.py

Co-authored-by: Maria Schuld <maria@xanadu.ai>

* Update pennylane/operation.py

Co-authored-by: Maria Schuld <maria@xanadu.ai>

* communting evolution cannot (and thus should not) declare num_params on the class level

* moved num_params test to later in Operation.__init__()
added comments to provide more context
fixed typo

* reverting change in operation.py becaseu they are not needed

* test all ways of declaring num_params

* Update doc/releases/changelog-dev.md

Co-authored-by: Maria Schuld <maria@xanadu.ai>

* removed optional test

Co-authored-by: Maria Schuld <maria@xanadu.ai>

* black

* Update doc/releases/changelog-dev.md

Co-authored-by: Josh Izaac <josh146@gmail.com>
Co-authored-by: Maria Schuld <maria@xanadu.ai>
Co-authored-by: Maria Schuld <mariaschuld@gmail.com>
Co-authored-by: antalszava <antalszava@gmail.com>

* Extended list of contributors

* QChem

* minor

* section names

* Updated non_parametric ops adjoint method and added test (#2133)

* Updated non_parametric ops adjoint method and added test

* changelog

* lint

* fixed testing bug

* lint

* moving updated adjoint logic into the Operation class and override this method in Observable class

* updated black (#2141)

* Add tape to graph conversion for circuit cutting (#2107)

* add WireCut operator, add qcut package, update docs

* add unit test

* update changelog

* updates

* add tape to graph conversion and unit test

* add unit tests

* add obs to node tests

* restructure qcut module

* add tests for observable and measurement conversion to nodes, update stateprep conversion logic

* fix pylint

* Apply suggestions from code review

Co-authored-by: Tom Bromley <49409390+trbromley@users.noreply.github.com>

* add code review suggestions

* add unit tests

* format

* Apply suggestions from code review

Co-authored-by: Tom Bromley <49409390+trbromley@users.noreply.github.com>

* add review suggestions

* Update pennylane/transforms/qcut.py

Co-authored-by: Tom Bromley <49409390+trbromley@users.noreply.github.com>

Co-authored-by: Tom Bromley <49409390+trbromley@users.noreply.github.com>

* add fix and tests (#2145)

* Incrementing the version number to `0.22.0-dev` (#2142)

* clean changelog-dev

* version bump

* mark current and dev release in the changelog

* Add Qchem v0.21.0 release notes

* Over wrote adjoint method for these templates as they inherit from Operations

* implemented adjoint method for a few more templates

* `WireCut` nodes can be replaced with `MeasureNode` and `PrepareNode` (#2124)

* add WireCut operator, add qcut package, update docs

* add unit test

* update changelog

* updates

* add tape to graph conversion and unit test

* add unit tests

* add obs to node tests

* restructure qcut module

* add tests for observable and measurement conversion to nodes, update stateprep conversion logic

* fix pylint

* add method to replace Wirecut ops with Measure and Prepare ops

* add unit tests

* add unit tests, update changelog

* format

* set measure and prepare node order to be equal (remove 0.5)

* Apply suggestions from code review

Co-authored-by: Tom Bromley <49409390+trbromley@users.noreply.github.com>

* add code review suggestions

* add unit tests

* format

* format

* Apply suggestions from code review

Co-authored-by: Tom Bromley <49409390+trbromley@users.noreply.github.com>

* add review suggestions

* Update pennylane/transforms/qcut.py

Co-authored-by: Tom Bromley <49409390+trbromley@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: Tom Bromley <49409390+trbromley@users.noreply.github.com>

* add review suggestions

* add unit test

* update changelog

* update changelog-0.21.0

* Apply suggestions from code review

Co-authored-by: Tom Bromley <49409390+trbromley@users.noreply.github.com>

* apply review suggestions

* Apply suggestions from code review

Co-authored-by: Tom Bromley <49409390+trbromley@users.noreply.github.com>

Co-authored-by: Tom Bromley <49409390+trbromley@users.noreply.github.com>

* Update changelog-0.21.0.md (#2149)

Co-authored-by: antalszava <antalszava@gmail.com>

* reset to previous soln

* clean

* more cleaning

* addressing code-review comments

* lint

* remove qcut feature

* reset changelogs

* reset logs

* updated changelog and qchem version

Co-authored-by: Christina Lee <christina@xanadu.ai>
Co-authored-by: anthayes92 <34694788+anthayes92@users.noreply.github.com>
Co-authored-by: Tom Bromley <49409390+trbromley@users.noreply.github.com>
Co-authored-by: antalszava <antalszava@gmail.com>
Co-authored-by: Nathan Killoran <co9olguy@users.noreply.github.com>

* section name and remove imports

* add paper ref

* tapering example

* Update doc/releases/changelog-0.21.0.md

Co-authored-by: Josh Izaac <josh146@gmail.com>

* Update doc/releases/changelog-0.21.0.md

Co-authored-by: Josh Izaac <josh146@gmail.com>

* Update doc/releases/changelog-0.21.0.md

Co-authored-by: Josh Izaac <josh146@gmail.com>

* Update doc/releases/changelog-0.21.0.md

Co-authored-by: Josh Izaac <josh146@gmail.com>

* Update doc/releases/changelog-0.21.0.md

Co-authored-by: Josh Izaac <josh146@gmail.com>

* Breaking changes

* Improvements order

* Update doc/releases/changelog-0.21.0.md

Co-authored-by: Josh Izaac <josh146@gmail.com>

* Update doc/releases/changelog-0.21.0.md

Co-authored-by: Josh Izaac <josh146@gmail.com>

* Update doc/releases/changelog-0.21.0.md

Co-authored-by: Josh Izaac <josh146@gmail.com>

* no well known imports

* apply latest suggestion to the tapering example

* JAX

* Update doc/releases/changelog-0.21.0.md

Co-authored-by: Josh Izaac <josh146@gmail.com>

* Update doc/releases/changelog-0.21.0.md

Co-authored-by: Josh Izaac <josh146@gmail.com>

* Update doc/releases/changelog-0.21.0.md

Co-authored-by: Josh Izaac <josh146@gmail.com>

* trainable weights

* Update doc/releases/changelog-0.21.0.md

Co-authored-by: Josh Izaac <josh146@gmail.com>

* Update doc/releases/changelog-0.21.0.md

Co-authored-by: Josh Izaac <josh146@gmail.com>

* Roto move up

* PR link move up

* Apply suggested headlines

* Apply Rotosolve rephrasing

* emojis

* Fix `dev.num_executions` bug with QNode caching (#2171)

* fix & test

* format

* changelog

* use _tape_cached private attribute on the QNode

* format

* PR number

* changelog

* remove unnecessary comment

* Update doc/releases/changelog-dev.md

Co-authored-by: Josh Izaac <josh146@gmail.com>

Co-authored-by: Josh Izaac <josh146@gmail.com>

* fixed bug when trying to insert around an observable (#2172)

* fixed bug when trying to insert around an observable (or any operation that also inherits from other classes), added tests

* fixed bug in test

* fixing bug in test again

* quick typo fix

* changelog

Co-authored-by: antalszava <antalszava@gmail.com>

* Roto description

* Update doc/releases/changelog-0.21.0.md

Co-authored-by: Josh Izaac <josh146@gmail.com>

* black examples

* Update doc/releases/changelog-0.21.0.md

Co-authored-by: Josh Izaac <josh146@gmail.com>

* remove new lines and suggested sentence

* apply suggestion

* full stop

* Add warnings for the gradient transforms when there are no trainable parameters (#2156)

* Add warnings (tape/qnode) with no trainable params

* Generalize warning + add tests

* Expand warning to all gradient transforms

Also fixes one test warning about shots.

* Add changelog

* code review: warning wording, separate asserts

Co-authored-by: antalszava <antalszava@gmail.com>

* code review: warning wording

* Formatting

* Parametrize qnode tests by interface

* Include finite_difference grad transform

use seperate asserts across tests

* Add import skips for interfaces

Co-authored-by: antalszava <antalszava@gmail.com>

* Deprecate `QubitDevice`'s caching (#2154)

* Add warning and test

* no print

* format

* format

* changelog

* add preferred way of caching

* mark current release

* change an example

* require Lightning v0.21.0 or higher in setup.py

* re-add dev changelog

* `v0.21.0` release notes (#2159)

* changelog typos

* PL version bump

* add 0.21.0 file

* create sections

* org

* update

* correct examples

* Extended list of contributors

* QChem

* minor

* section names

* section name and remove imports

* add paper ref

* tapering example

* Update doc/releases/changelog-0.21.0.md

Co-authored-by: Josh Izaac <josh146@gmail.com>

* Update doc/releases/changelog-0.21.0.md

Co-authored-by: Josh Izaac <josh146@gmail.com>

* Update doc/releases/changelog-0.21.0.md

Co-authored-by: Josh Izaac <josh146@gmail.com>

* Update doc/releases/changelog-0.21.0.md

Co-authored-by: Josh Izaac <josh146@gmail.com>

* Update doc/releases/changelog-0.21.0.md

Co-authored-by: Josh Izaac <josh146@gmail.com>

* Breaking changes

* Improvements order

* Update doc/releases/changelog-0.21.0.md

Co-authored-by: Josh Izaac <josh146@gmail.com>

* Update doc/releases/changelog-0.21.0.md

Co-authored-by: Josh Izaac <josh146@gmail.com>

* Update doc/releases/changelog-0.21.0.md

Co-authored-by: Josh Izaac <josh146@gmail.com>

* no well known imports

* apply latest suggestion to the tapering example

* JAX

* Update doc/releases/changelog-0.21.0.md

Co-authored-by: Josh Izaac <josh146@gmail.com>

* Update doc/releases/changelog-0.21.0.md

Co-authored-by: Josh Izaac <josh146@gmail.com>

* Update doc/releases/changelog-0.21.0.md

Co-authored-by: Josh Izaac <josh146@gmail.com>

* trainable weights

* Update doc/releases/changelog-0.21.0.md

Co-authored-by: Josh Izaac <josh146@gmail.com>

* Update doc/releases/changelog-0.21.0.md

Co-authored-by: Josh Izaac <josh146@gmail.com>

* Roto move up

* PR link move up

* Apply suggested headlines

* Apply Rotosolve rephrasing

* emojis

* Roto description

* Update doc/releases/changelog-0.21.0.md

Co-authored-by: Josh Izaac <josh146@gmail.com>

* black examples

* Update doc/releases/changelog-0.21.0.md

Co-authored-by: Josh Izaac <josh146@gmail.com>

* remove new lines and suggested sentence

* apply suggestion

* full stop

* mark current release

* change an example

Co-authored-by: Josh Izaac <josh146@gmail.com>

* Bump the requirement of PennyLane-Lightning to v0.21.0 in `setup.py` (#2177)

* Bump the requirement of PennyLane-Lightning in setup.py

* Update setup.py

* Update setup.py

Co-authored-by: Josh Izaac <josh146@gmail.com>

* merge

* more

Co-authored-by: David Ittah <dime10@users.noreply.github.com>
Co-authored-by: Christina Lee <christina@xanadu.ai>
Co-authored-by: soranjh <40344468+soranjh@users.noreply.github.com>
Co-authored-by: Romain <rmoyard@gmail.com>
Co-authored-by: Josh Izaac <josh146@gmail.com>
Co-authored-by: cvjjm <60615188+cvjjm@users.noreply.github.com>
Co-authored-by: Maria Schuld <maria@xanadu.ai>
Co-authored-by: Maria Schuld <mariaschuld@gmail.com>
Co-authored-by: Jay Soni <jbsoni@uwaterloo.ca>
Co-authored-by: anthayes92 <34694788+anthayes92@users.noreply.github.com>
Co-authored-by: Tom Bromley <49409390+trbromley@users.noreply.github.com>
Co-authored-by: Nathan Killoran <co9olguy@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants