-
Notifications
You must be signed in to change notification settings - Fork 39
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 support for float and double precision data #113
Conversation
Hello. You may have forgotten to update the changelog!
|
Codecov Report
@@ Coverage Diff @@
## master #113 +/- ##
=======================================
Coverage 98.14% 98.14%
=======================================
Files 3 3
Lines 54 54
=======================================
Hits 53 53
Misses 1 1
Continue to review full report at Codecov.
|
[ch7526] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @mlxd! This looks to have tidied things up nicely 💯
StateVector(CFP_t *arr, size_t length) | ||
: arr_{arr}, length_{length}, num_qubits_{Util::log2(length_)}, | ||
gate_wires_{ | ||
{"PauliX", 1}, {"PauliY", 1}, {"PauliZ", 1}, {"Hadamard", 1}, | ||
{"T", 1}, {"S", 1}, {"RX", 1}, {"RY", 1}, | ||
{"RZ", 1}, {"Rot", 1}, {"PhaseShift", 1}, {"CNOT", 2}, | ||
{"SWAP", 2}, {"CZ", 2}, {"CRX", 2}, {"CRY", 2}, | ||
{"CRZ", 2}, {"CRot", 2}, {"CSWAP", 3}, {"Toffoli", 3}}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I got a bit lost here, would you be able to give a quick rundown of what's going on?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure thing. The previous implementation had some logic to check the gate classes for the number of supported wires to act upon. Since the classes are now methods, the mapping of a gate label to supported wires needed to be elsewhere. I created a private dictionary to map between gate labels and the number of supported wires (gate_wires_
). This allows minimal changes to the apply methods to match the older functionality.
Since the dictionary is declared as const
it must be initialised with this initialiser list syntax. Though, we can move these to a inline static const / constexpr
and put it outside the class instantiation, though for now I think this is fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
static constexpr vector<CFP_t> getPauliX() { | ||
return {ZERO, ONE, ONE, ZERO}; | ||
} | ||
static constexpr vector<CFP_t> getPauliY() { | ||
return {ZERO, -IMAG, IMAG, ZERO}; | ||
} | ||
static constexpr vector<CFP_t> getPauliZ() { | ||
return {ONE, ZERO, ZERO, -ONE}; | ||
} | ||
static constexpr vector<CFP_t> getHadamard() { | ||
return {INVSQRT2, INVSQRT2, INVSQRT2, -INVSQRT2}; | ||
} | ||
static constexpr vector<CFP_t> getS() { return {ONE, ZERO, ZERO, IMAG}; } | ||
static constexpr vector<CFP_t> getT() { return {ONE, ZERO, ZERO, IMAG}; } | ||
static constexpr vector<CFP_t> getCNOT() { | ||
return {ONE, ZERO, ZERO, ZERO, ZERO, ONE, ZERO, ZERO, | ||
ZERO, ZERO, ZERO, ONE, ZERO, ZERO, ONE, ZERO}; | ||
} | ||
static constexpr vector<CFP_t> getSWAP() { | ||
return {ONE, ZERO, ZERO, ZERO, ZERO, ZERO, ONE, ZERO, | ||
ZERO, ONE, ZERO, ZERO, ZERO, ZERO, ZERO, ONE}; | ||
} | ||
static constexpr vector<CFP_t> getCZ() { | ||
return {ONE, ZERO, ZERO, ZERO, ZERO, ONE, ZERO, ZERO, | ||
ZERO, ZERO, ONE, ZERO, ZERO, ZERO, ZERO, -ONE}; | ||
} | ||
|
||
static constexpr vector<CFP_t> getCSWAP() { | ||
return {ONE, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ONE, | ||
ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ONE, ZERO, | ||
ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ONE, ZERO, ZERO, | ||
ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ONE, ZERO, ZERO, ZERO, | ||
ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ONE, ZERO, ZERO, ZERO, | ||
ZERO, ZERO, ZERO, ONE, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, | ||
ZERO, ZERO, ZERO, ONE}; | ||
} | ||
static constexpr vector<CFP_t> getToffoli() { | ||
return {ONE, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ONE, | ||
ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ONE, ZERO, | ||
ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ONE, ZERO, ZERO, | ||
ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ONE, ZERO, ZERO, ZERO, | ||
ZERO, ZERO, ZERO, ZERO, ZERO, ONE, ZERO, ZERO, ZERO, ZERO, | ||
ZERO, ZERO, ZERO, ZERO, ZERO, ONE, ZERO, ZERO, ZERO, ZERO, | ||
ZERO, ZERO, ONE, ZERO}; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I understand correctly, these aren't used anywhere but are just defined for completeness?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. These were all defined for each gate class so I implemented them for brevity. Since we do not use them here though it may be fine to move them to a separate header/class. What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we just remove them entirely (unless we expect to use in future?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, pulling them out of here seems fine. I use some of these for the tests, and I think it will be good practice to allow pulling the gate definition out as needed, so will likely just move these to their own namespace Pennylane::Gates
and allow them to be called from there.
…ntation (#115) * Add preliminary catch2 support * Move private methods to public for testing * Overload applyOperations for param and non param calls * Add testing support for X,Y,Z,H gates * Add S, T gate tests * Add support for RX,RY,RZ gate tests * Add PhaseShift gate tests * Add Rot tests * Add CNOT tests * Add support for CSWAP, Toffoli, CZ, CRot tests * Update testing CI * Fix CodeFactor complaints * Update CI image before running tests * Favour use of reverse iterator over counter in for loops * Fix contructor tests * Fix formatting * Fix narrowing complaints * Fix MSVC math errors * Run black * Remove unneeded ops for real*complex products * Fix test builder * Ensure cmake has a version to avoid warnings * Fix formatting of SV * Fix test reporting
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Really awesome work Lee. I left a few comments. Since I just joined, it might be due to my lack of familiarity, but I was wondering why there are gate definitions in two different places in the code, e.g. getCSWAP in StateVector.hpp and CSWAP in GateData.hpp, is this a necessity?
const FMap gates_; | ||
const std::unordered_map<string, size_t> gate_wires_; | ||
|
||
CFP_t *const arr_; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we change to smart pointers? e.g unique_ptr?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a carry-over of the original design which does state-prep in numpy. To access the numpy data we point the above pointer to it via the available binding logic. I wish to completely remove the numpy prep (to be followed in a subsequent PR) and replace it with a std::vector in Cpp.
For now, I'd rather not tamper with the existing implementation (shared would be best, but not sure how numpy would handle it), since CPP doesn't own the pointer, merely just operates on it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds like a good plan
/** | ||
* @brief Get indices not participating in operation. | ||
* | ||
* @param indicesToExclude |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing some description here for the parameters I think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yea, the docs need to follow. We have a story created for this, as the entire class docs need an update.
GateData.hpp was a carry-over from the googletest suite. I updated them, then decided to pull them out. You are completely correct that it can be pulled. I'll removed all the remnants of the old testing suite. |
Recent changes have pulled the gate definitions from the class (fixes the CodeFactor complaint on StateVector), moved them to their own separate namespace, and used these to assist in the tests. This also fixed the second CodeFactor complaint. I think anything else needed removal of unused libs can be moved to a separate PR and story once we have some spare time. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💯
### Improvements | ||
|
||
- C++ tests have been ported to use Catch2 framework. ([#115](https://github.com/PennyLaneAI/pennylane-lightning/pull/115)) | ||
|
||
- Testing now exists for both float and double precision methods in C++ layer. ([#113](https://github.com/PennyLaneAI/pennylane-lightning/pull/113),[#115](https://github.com/PennyLaneAI/pennylane-lightning/pull/115)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Testing now exists for both float and double precision methods in C++ layer. ([#113](https://github.com/PennyLaneAI/pennylane-lightning/pull/113),[#115](https://github.com/PennyLaneAI/pennylane-lightning/pull/115)) | |
- Testing now exists for both float and double precision methods in C++ layer. ([#113](https://github.com/PennyLaneAI/pennylane-lightning/pull/113), [#115](https://github.com/PennyLaneAI/pennylane-lightning/pull/115)) |
I will update the implementation for the new gate, then merge. |
Context: This PR will enable support for 64bit and 128bit complex datatypes, as well as restructuring the package class to allow for this extension.
Description of the Change: To enable the above, several modifications were required:
Gates.hpp
andGates.cpp
are now part of theStateVector
class, with gate numeric values accessible inGates.hpp
.Apply.hpp
andApply.cpp
has been added to theStateVector
class directlyStateVector
class was converted to a templated class, allowing all above functions to be compiled with the correct data types.inline static const
, template argument deduction, constexpr if)StateVector
class and methods can now be directly accessed from Python, using theStateVectorC64
andStateVectorC128
types. Use will require adaption of core Python implementation to utilise.Benefits: This enables use of data-types previously unavailable without casting (np.complex64), and will allow for memory and performance savings when used. Features spread over multiple additional classes and files are now made redundant, allowing for a more straight-forward implementation.
Possible Drawbacks: Structure of
StateVector
class has increased in size.Related GitHub Issues: