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 C++ adjoint diff methods #136

Merged
merged 76 commits into from
Sep 13, 2021
Merged

Add C++ adjoint diff methods #136

merged 76 commits into from
Sep 13, 2021

Conversation

mlxd
Copy link
Member

@mlxd mlxd commented Aug 19, 2021

Context: This PR will add C++ support for adjoint diff, based on arXiV: arXiV:2009.02823.

Description of the Change:

  • StateVectorManaged class added as a subclass of StateVector, where memory management is handled internally by the class.
  • AdjointDiff.hpp file added, with AdjointJacobian and helper classes to prepare and calculate the Jacobian for a given set of parameters and observables. For multiple observables, the calculations are handled independently by OpenMP threads and populate the Jacobian.
  • std::variant based functionality used to distinguish between parametric gates, non parametric gates, and arbitrary gates defined by a list of complex parameters.
  • MacOS wheelbuilder compiler updated to use brew-install clang for x86, as default compiler uses an older version of the Xcode SDK not supporting std::variant.
  • Repo refactored into subdirectories for multiple separate components:
    algorithms for algorithms using and to be used by the simulator; bindings for source files directly related to binding the C++ code with Python; simulator for source-files directly related to the simulator; util for utility functions to be used across the package;
  • Each subdirectory has now been compartmentalized with CMake, allowing separable compilation of each translation unit, enabling C++ system binaries as well as Python bindings to be built.
  • Extensive testing for all of the above.
  • Bug-fix for the CRY gate, which had an incorrect index.

Benefits: C++ backed adjoint method is much faster (4x-6x) than Python.

Possible Drawbacks: Requires modern C++17 knowledge to maintain. Design may require some later refactor.

Related GitHub Issues:

@github-actions
Copy link
Contributor

Hello. You may have forgotten to update the changelog!
Please edit .github/CHANGELOG.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 Aug 19, 2021

Codecov Report

Merging #136 (e1d569f) into master (9627d7f) will not change coverage.
The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff             @@
##            master      #136    +/-   ##
==========================================
  Coverage   100.00%   100.00%            
==========================================
  Files            3         4     +1     
  Lines           71       182   +111     
==========================================
+ Hits            71       182   +111     
Impacted Files Coverage Δ
pennylane_lightning/_serialize.py 100.00% <100.00%> (ø)
pennylane_lightning/lightning_qubit.py 100.00% <100.00%> (ø)

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 9627d7f...e1d569f. Read the comment docs.

@github-actions
Copy link
Contributor

github-actions bot commented Aug 19, 2021

Test Report (C++) on Ubuntu

       1 files  ±0         1 suites  ±0   0s ⏱️ ±0s
   327 tests ±0     327 ✔️ ±0  0 💤 ±0  0 ❌ ±0 
1 185 runs  ±0  1 185 ✔️ ±0  0 💤 ±0  0 ❌ ±0 

Results for commit 6112aec. ± Comparison against base commit 6112aec.

♻️ This comment has been updated with latest results.

mlxd and others added 5 commits September 1, 2021 15:47
* Update tests

* Add problematic statements

* Fix tests

* Fix type hinting

* Make function as expected

* Add quick return for no jacobian

* Move position

* Add raise for non supported ops

* Ensure jacobian shape formatted as expected

* Return jacobian directly as numpy array

* Ensure correct return type of jacobian

* Ensure param number tracking is correct for adjjac

* Fix CRY gate index

* All tests passing

* Calculate parametric ops when creating opsdata object

* Apply formatting

* Ensure MacOS wheel builder uses a more modern compiler toolchain

* Fix mac wheel builder

Co-authored-by: Lee J. O'Riordan <loriordan@gmail.com>
@mlxd mlxd marked this pull request as ready for review September 3, 2021 16:41
@mlxd
Copy link
Member Author

mlxd commented Sep 3, 2021

Just a note, CodeFactor seems to be caching old runs and using those --- please ignore its Action failure.

Copy link
Contributor

@trbromley trbromley left a comment

Choose a reason for hiding this comment

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

Thanks @mlxd! Thanks for putting in so much awesome work to get this done! Everything looks great to me, my only question is the failing tests in #142.

Comment on lines +56 to +57
CC: /usr/local/opt/llvm/bin/clang
CXX: /usr/local/opt/llvm/bin/clang++
Copy link
Contributor

Choose a reason for hiding this comment

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

Is the CC option for C (i.e., the language)? Do we need it?

Copy link
Member Author

Choose a reason for hiding this comment

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

Good point, and you are right. Removing CC should be fine (though I'll test it out). There may be a way to avoid use of this too, though I must check this out first.

wires_map (dict): a dictionary mapping input wires to the device's backend wires

Returns:
Tuple[list, list, list, list, list]: A serialization of the operations, containing a list
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
Tuple[list, list, list, list, list]: A serialization of the operations, containing a list
Tuple[Tuple[list, list, list, list, list], bool]: A serialization of the operations as a
tuple of lists and a flag indicating whether non-default state preparation is used in the
tape.


def _serialize_ops(
tape: QuantumTape, wires_map: dict
) -> Tuple[List[List[str]], List[np.ndarray], List[List[int]], List[bool], List[np.ndarray]]:
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
) -> Tuple[List[List[str]], List[np.ndarray], List[List[int]], List[bool], List[np.ndarray]]:
) -> Tuple[Tuple[List[List[str]], List[np.ndarray], List[List[int]], List[bool], List[np.ndarray]], bool]:

Copy link
Member Author

Choose a reason for hiding this comment

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

While this should be fine, I wonder will it mess with the conversion to C++ (though I'd imagine pybind is clever enough that we do need to be explicit).

Comment on lines 149 to 150
if not CPP_BINARY_AVAILABLE:
return super().adjoint_jacobian(tape, starting_state, use_device_state)
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need this? Since LightningQubit is reset to DefaultQubit if CPP_BINARY_AVAILABLE (see lines 205 and after)

.github/workflows/tests.yml Show resolved Hide resolved
pennylane_lightning/src/algorithms/AdjointDiff.hpp Outdated Show resolved Hide resolved
pennylane_lightning/src/bindings/Bindings.cpp Show resolved Hide resolved
pennylane_lightning/src/simulator/StateVectorManaged.hpp Outdated Show resolved Hide resolved
pennylane_lightning/src/util/Error.hpp Show resolved Hide resolved
* Add test for dev pl

* Add test

* Move to original tests

* Add additional ops creation method

* Fix QFT errors

* Reformat

* Revert "Fix QFT errors"

This reverts commit f62a763.

* Preclude certain gates

* Update test

* Add double comments

* Update test

* Add tests for standard and custom wire labels

* Remove print

* Extend tests for RX,RY

* Prevent trainable params from going negative

* Ensure correct coef applied when using generator

* Update Ops repr

* Reenable tests

* Update CI for non compiled builds

* Add exception for Projector observable

* Add Hermitian in tensor product

* Ensure data is passed as complex128 to cpp

* Run black

* Ensure serialisation of numpy data is cast correctly

* Remove redundant methods

* Add support to get obs data

* Fix serialize test array structures

* Add hermitian checks

* Ensure testing complete for current requirements

* Reformat bindings

* Skip test for Hermitian on default

* Ensure bin available passed as class param

* Skip for non binary tests

Co-authored-by: Lee J. O'Riordan <loriordan@gmail.com>
Copy link
Contributor

@trevor-vincent trevor-vincent left a comment

Choose a reason for hiding this comment

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

Awesome work Lee, just two minor comments.

pennylane_lightning/src/tests/Test_AdjDiff.cpp Outdated Show resolved Hide resolved
mlxd and others added 10 commits September 13, 2021 08:50
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: Tom Bromley <49409390+trbromley@users.noreply.github.com>
Co-authored-by: Tom Bromley <49409390+trbromley@users.noreply.github.com>
Co-authored-by: Tom Bromley <49409390+trbromley@users.noreply.github.com>
@mlxd
Copy link
Member Author

mlxd commented Sep 13, 2021

Thanks for the reviews all. As per our chat on Friday I'm ignoring the codefactor report and merging this, as it still fails to remove the cached version.

@mlxd mlxd merged commit 6112aec into master Sep 13, 2021
@mlxd mlxd deleted the 7072_adj_diff branch September 13, 2021 09:24
Comment on lines +20 to +21
* PennyLane-Lightning now has support for the adjoint Jacobian method of http://arxiv.org/abs/2009.02823.
[(136)](https://github.com/PennyLaneAI/pennylane-lightning/pull/136)
Copy link
Contributor

Choose a reason for hiding this comment

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

For me this is a major new feature 🚀 🎉 We can probably move it up during release 😁

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.

4 participants