Skip to content

Commit e96a53f

Browse files
vincentmrgithub-actions[bot]AmintorDusko
authored
Template/expval (#489)
* M pennylane_lightning/core/src/bindings/Bindings.hpp; hack `JacobianData` to work with devices. M pennylane_lightning/core/src/simulators/lightning_kokkos/StateVectorKokkos.hpp; `applyMatrix` bugfix: use intermediate hostview to copy matrix data; same bugfix for `getDataVector`. M pennylane_lightning/core/src/simulators/lightning_kokkos/algorithms/AdjointJacobianKokkos.hpp; use copy constructor. M pennylane_lightning/core/src/simulators/lightning_kokkos/measurements/MeasurementsKokkos.hpp; use copy constructor. M pennylane_lightning/core/src/simulators/lightning_kokkos/observables/ObservablesKokkos.hpp; use copy constructor. M requirements-dev.txt; add clang-format-14. * Auto update version * Update changelog. * Auto update version * Auto update version * Add an argument to adjointJacobian to avoid syncing and copying state vector data in adjoint-diff. * Reformat * trigger CI * [skip ci] Update changelog. * Introduce std::unordered_map<std::string, ExpValFunc> expval_funcs_. * Introduce applyExpectationValueFunctor. * Add binding to LKokkos expval(matrix, wires). Combine expval functor calls into two templated methods. Call specialized expval methods when possible. Remove obsolete 'Apply directly' tests. * Update changelog. * Add test for arbitrary expval(Hermitian). * Add getExpectationValueMultiQubitOpFunctor. * Add typename hint for macos. * Add typename macos. * Use Kokkos::ThreadVectorRange policy for innerloop in getExpectationValueMultiQubitOpFunctor. * Auto update version * Auto update version * Couple fix for HIP. * WIP * Add specialized 3-5 qubit expval functors. * Add implementation notes. * [skip ci] Polish getExpValMatrix and limit getExpValNQubitOpFunctor to N == 4 (seems optimal on OPENMP/HIP backends although CUDA can go further). * Fix whitespace warning. * Auto update version * Use simplified bitshifts in 1- & 2-qubit expval kernels. * Update tests. * Update changelog. * Bump pennylane version. * Auto update version * Reimplement expval functors with macros. * Auto update version * Update CHANGELOG.md * Auto update version * trigger CI * trigger CI * Bump Kokkos to 4.1.00 in CI. * Revert kokkos ver. * Add tests for macroed expval functors. * Remove redundant black lines. * Use matrix interface to get expval of HermitianObs in LKokkos. * Cover kokkos_args error. --------- Co-authored-by: Dev version update bot <github-actions[bot]@users.noreply.github.com> Co-authored-by: Amintor Dusko <[email protected]>
1 parent 8eed6f2 commit e96a53f

File tree

11 files changed

+709
-117
lines changed

11 files changed

+709
-117
lines changed

.github/CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212

1313
### Improvements
1414

15+
* Refactor LKokkos `Measurements` class to use Kokkos `RangePolicy` together with special functors to obtain the expectation value of 1- to 4-wire generic unitary gates. For more than 4 wires, the general implementation using Kokkos `TeamPolicy` is employed to yield the best all-around performance.
16+
[(#489)] (https://github.com/PennyLaneAI/pennylane-lightning/pull/489)
17+
1518
* Add tests to increase LKokkos coverage.
1619
[(#485)](https://github.com/PennyLaneAI/pennylane-lightning/pull/485)
1720

pennylane_lightning/core/_version.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,4 @@
1616
Version number (major.minor.patch[-label])
1717
"""
1818

19-
__version__ = "0.33.0-dev3"
19+
__version__ = "0.33.0-dev4"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# Implementation
2+
3+
## Expval kernels
4+
5+
The general multi-qubit operator kernel requires a private variable `coeffs_in` to store state vector coefficients.
6+
In the Kokkos framework, this variable cannot be a private member of the functor, say, because all threads will overwrite it.
7+
One must then use `TeamPolicy`s together with `scratch_memory_space` which allows creating and manipulating thread-local variables.
8+
This implementation however appears suboptimal compared with the straightforward `RangePolicy` with bit-injection one.
9+
10+
The last being more verbose, it is only implemented for 1- and 2-qubit observables.
11+
It is however possible to generate the code automatically for higher qubit counts with the following Python script.
12+
13+
```python
14+
for n_wires in range(1, 6):
15+
name = f"getExpVal{n_wires}QubitOpFunctor"
16+
nU = 2**n_wires
17+
18+
print(
19+
f"""template <class PrecisionT, std::size_t n_wires> struct {name} {{
20+
21+
using ComplexT = Kokkos::complex<PrecisionT>;
22+
using KokkosComplexVector = Kokkos::View<ComplexT *>;
23+
using KokkosIntVector = Kokkos::View<std::size_t *>;
24+
25+
KokkosComplexVector arr;
26+
KokkosComplexVector matrix;
27+
KokkosIntVector wires;
28+
std::size_t dim;
29+
std::size_t num_qubits;
30+
31+
{name}(const KokkosComplexVector &arr_,
32+
const std::size_t num_qubits_,
33+
const KokkosComplexVector &matrix_,
34+
const KokkosIntVector &wires_) {{
35+
wires = wires_;
36+
arr = arr_;
37+
matrix = matrix_;
38+
num_qubits = num_qubits_;
39+
dim = 1U << wires.size();
40+
}}
41+
42+
KOKKOS_INLINE_FUNCTION
43+
void operator()(const std::size_t k, PrecisionT &expval) const {{
44+
const std::size_t kdim = k * dim;
45+
"""
46+
)
47+
48+
for k in range(nU):
49+
print(
50+
f"""
51+
std::size_t i{k:0{n_wires}b} = kdim | {k};
52+
for (std::size_t pos = 0; pos < n_wires; pos++) {{
53+
std::size_t x =
54+
((i{k:0{n_wires}b} >> (n_wires - pos - 1)) ^
55+
(i{k:0{n_wires}b} >> (num_qubits - wires(pos) - 1))) &
56+
1U;
57+
i{k:0{n_wires}b} = i{k:0{n_wires}b} ^ ((x << (n_wires - pos - 1)) |
58+
(x << (num_qubits - wires(pos) - 1)));
59+
}}
60+
"""
61+
)
62+
63+
# print("expval += real(")
64+
for k in range(nU):
65+
tmp = f"expval += real(conj(arr(i{k:0{n_wires}b})) * ("
66+
tmp += f"matrix(0B{k:0{n_wires}b}{0:0{n_wires}b}) * arr(i{0:0{n_wires}b})"
67+
for j in range(1, nU):
68+
tmp += (
69+
f" + matrix(0B{k:0{n_wires}b}{j:0{n_wires}b}) * arr(i{j:0{n_wires}b})"
70+
)
71+
print(tmp, end="")
72+
print("));")
73+
print("}")
74+
print("};")
75+
```

pennylane_lightning/core/src/simulators/lightning_kokkos/measurements/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ target_link_libraries(${PL_BACKEND}_measurements INTERFACE lightning_compile_op
1111
lightning_observables
1212
lightning_utils
1313
${PL_BACKEND}
14+
${PL_BACKEND}_observables
1415
${PL_BACKEND}_utils
1516
)
1617

0 commit comments

Comments
 (0)