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 native PauliRot implementation in LightningKokkos [sc-71642] #855

Merged
merged 73 commits into from
Sep 10, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
9cda69a
Implement native PauliRot in LightningQubit.
vincentmr Jul 30, 2024
37418d9
Fix issues wih I in pauli word.
vincentmr Jul 31, 2024
e0d5377
Directly get indices and data.
vincentmr Jul 31, 2024
0266860
Change core_function signature for applyNCN
vincentmr Jul 31, 2024
5d49dab
Include sin in data.
vincentmr Jul 31, 2024
0a7a97e
*= c while copying arr.
vincentmr Jul 31, 2024
06675c7
Use numpy request to pass pointers.
vincentmr Jul 31, 2024
9e6863f
generateBitPatterns
vincentmr Jul 31, 2024
c915b96
Permute early.
vincentmr Aug 1, 2024
3a29b66
Do not precompute offsets.
vincentmr Aug 1, 2024
e74a2d4
Modify stopping_condition and clean up.
vincentmr Aug 1, 2024
1e6d324
Clean up
vincentmr Aug 1, 2024
8f3c99f
Auto update version from '0.38.0-dev20' to '0.38.0-dev22'
ringo-but-quantum Aug 1, 2024
1645a5a
Fix device test.
vincentmr Aug 2, 2024
8cca37e
Replace indices, data arguments by word for PauliRot.
vincentmr Aug 2, 2024
4a51fc6
Auto update version from '0.38.0-dev22' to '0.38.0-dev25'
ringo-but-quantum Aug 2, 2024
3d10b73
Merge branch 'master' into lq_pauli_rot
vincentmr Aug 2, 2024
aa24f4d
Fix few lint warnings.
vincentmr Aug 2, 2024
6927caf
Update changelog
vincentmr Aug 2, 2024
ee34eeb
Fix docstring.
vincentmr Aug 2, 2024
c9dc41e
Fix docstrings.
vincentmr Aug 5, 2024
c702b64
Merge remote-tracking branch 'origin/master' into lq_pauli_rot
vincentmr Aug 5, 2024
9bb5a8a
Auto update version from '0.38.0-dev25' to '0.38.0-dev26'
ringo-but-quantum Aug 5, 2024
6cb0f8e
Update GateIndices.hpp
vincentmr Aug 5, 2024
b8488c2
WIP loops
vincentmr Aug 6, 2024
670570f
Avoid copying arr into coeffs.
vincentmr Aug 7, 2024
bc58a7d
Comment code a bit.
vincentmr Aug 7, 2024
f43a77f
Auto update version from '0.38.0-dev26' to '0.38.0-dev27'
ringo-but-quantum Aug 7, 2024
6a79685
Apply suggestions from code review
vincentmr Aug 7, 2024
5bc8551
Revert to old implementation.
vincentmr Aug 8, 2024
32b9b34
Merge remote-tracking branch 'origin/lq_pauli_rot' into lq_pauli_rot
vincentmr Aug 8, 2024
b99e108
Add doc [skip ci].
vincentmr Aug 8, 2024
4b99691
Add PauliRot C++ tests.
vincentmr Aug 8, 2024
9072665
Merge branch 'master' into lq_pauli_rot
vincentmr Aug 8, 2024
2741f29
Reimplement applyPauliRot
vincentmr Aug 14, 2024
6326894
popcount
vincentmr Aug 14, 2024
73cfaed
Clean up.
vincentmr Aug 15, 2024
7b06ec1
Auto update version from '0.38.0-dev27' to '0.38.0-dev34'
ringo-but-quantum Aug 15, 2024
8762c39
Merge remote-tracking branch 'origin/master' into lq_pauli_rot
vincentmr Aug 15, 2024
9398b37
Merge remote-tracking branch 'origin/lq_pauli_rot' into lq_pauli_rot
vincentmr Aug 15, 2024
63ea43f
Fix setStateVecotr
vincentmr Aug 15, 2024
1b0aba9
Fix adjoint
vincentmr Aug 15, 2024
9059862
Fix tidy
vincentmr Aug 15, 2024
15b533e
Fix capture
vincentmr Aug 15, 2024
fe390cd
Merge branch 'master' into lq_pauli_rot
vincentmr Aug 15, 2024
f9bff5a
trigger ci
vincentmr Aug 15, 2024
e90ee3f
Clean up runner
vincentmr Aug 15, 2024
f04c69f
Auto update version from '0.38.0-dev34' to '0.38.0-dev35'
ringo-but-quantum Aug 15, 2024
0d1ad50
Fix tidy
vincentmr Aug 15, 2024
72d219f
sudo du -sh
vincentmr Aug 15, 2024
d1307f1
sudo du -sh
vincentmr Aug 15, 2024
2d37fdd
sudo du -sh
vincentmr Aug 15, 2024
b0f505e
sudo du -sh
vincentmr Aug 15, 2024
d8aea05
sudo du -sh
vincentmr Aug 15, 2024
509de91
sudo du -sh
vincentmr Aug 15, 2024
e46551b
sudo du -sh
vincentmr Aug 15, 2024
694f856
PauliRot in LK
vincentmr Aug 15, 2024
509c035
Update changelog [skip ci].
vincentmr Aug 15, 2024
f0d222e
Merge remote-tracking branch 'origin/master' into lk_pauli_rot
vincentmr Aug 20, 2024
131583f
Auto update version from '0.38.0-dev38' to '0.38.0-dev39'
ringo-but-quantum Aug 20, 2024
b36c48f
PauliRot => multirz
vincentmr Aug 20, 2024
e29c93c
Merge remote-tracking branch 'origin/master' into lk_pauli_rot
vincentmr Sep 5, 2024
3bdab93
Auto update version from '0.39.0-dev2' to '0.39.0-dev3'
ringo-but-quantum Sep 5, 2024
7d81d32
Merge branch 'master' into lk_pauli_rot
vincentmr Sep 5, 2024
be95a83
Auto update version from '0.39.0-dev4' to '0.39.0-dev5'
ringo-but-quantum Sep 5, 2024
4c3a365
Format
vincentmr Sep 5, 2024
e06fdab
Merge remote-tracking branch 'origin/master' into lk_pauli_rot
vincentmr Sep 9, 2024
210eb61
Add C++ tests
vincentmr Sep 9, 2024
0c37793
Merge remote-tracking branch 'origin/master' into lk_pauli_rot
vincentmr Sep 9, 2024
33ffd58
Merge branch 'master' into lk_pauli_rot
vincentmr Sep 10, 2024
3131c1f
Auto update version from '0.39.0-dev13' to '0.39.0-dev14'
ringo-but-quantum Sep 10, 2024
e4036ef
Merge branch 'master' into lk_pauli_rot
vincentmr Sep 10, 2024
391d0da
Auto update version from '0.39.0-dev14' to '0.39.0-dev15'
ringo-but-quantum Sep 10, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Replace indices, data arguments by word for PauliRot.
  • Loading branch information
vincentmr committed Aug 2, 2024
commit 8cca37e6d3073c532ed838221164a20942211d9b
Original file line number Diff line number Diff line change
Expand Up @@ -448,14 +448,13 @@ class StateVectorLQubit : public StateVectorBase<PrecisionT, Derived> {
const std::vector<std::size_t> &wires,
const bool inverse,
const std::vector<PrecisionT> &params,
const std::size_t *indices,
const std::complex<PrecisionT> *data) {
const std::string &word) {
PL_ABORT_IF_NOT(controlled_wires.size() == controlled_values.size(),
"`controlled_wires` must have the same size as "
"`controlled_values`.");
GateImplementationsLM::applyPauliRot<PrecisionT>(
this->getData(), this->getNumQubits(), controlled_wires,
controlled_values, wires, inverse, params[0], indices, data);
controlled_values, wires, inverse, params[0], word);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,12 +178,9 @@ void registerBackendClassSpecificBindings(PyClass &pyclass) {
[](StateVectorT &sv, const std::vector<std::size_t> &controlled_wires,
const std::vector<bool> &controlled_values,
const std::vector<std::size_t> &wires, const bool inverse,
const std::vector<ParamT> &params, const np_arr_sparse_ind &indices,
const np_arr_c &data) {
sv.applyPauliRot(
controlled_wires, controlled_values, wires, inverse, params,
static_cast<std::size_t *>(indices.request().ptr),
static_cast<std::complex<PrecisionT> *>(data.request().ptr));
const std::vector<ParamT> &params, const std::string &word) {
sv.applyPauliRot(controlled_wires, controlled_values, wires,
inverse, params, word);
},
"Apply a sparse operation.");
pyclass
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "Util.hpp" // exp2, maxDecimalForQubit

namespace Pennylane::LightningQubit::Gates {

auto getIndicesAfterExclusion(const std::vector<std::size_t> &indicesToExclude,
std::size_t num_qubits)
-> std::vector<std::size_t> {
Expand Down Expand Up @@ -47,4 +48,97 @@ auto generateBitPatterns(const std::vector<std::size_t> &qubitIndices,
}
return indices;
}

auto generatePauliWordIndices(const std::string &word)
-> std::vector<std::size_t> {
const std::size_t n_word = word.size();
const std::size_t n_indices = Pennylane::Util::exp2(n_word);
std::vector<std::size_t> indices(n_indices);
std::vector<std::size_t> mtype(n_word);
std::transform(word.begin(), word.end(), mtype.begin(), [](auto ch) {
return (ch == 'I' || ch == 'Z') ? 0UL : 1UL;
});
std::size_t current_size = 2;
indices[0] = 0UL;
indices[1] = 1UL;
if (mtype[n_word - 1 - 0] == 1) {
std::swap(indices[0], indices[1]);
}
for (std::size_t i = 1; i < n_word; i++) {
if (mtype[n_word - 1 - i] == 0) {
for (std::size_t j = 0; j < current_size; j++) {
indices[j + current_size] = indices[j] + current_size;
}
} else {
std::copy(indices.begin(), indices.begin() + current_size,
indices.begin() + current_size);
for (std::size_t j = 0; j < current_size; j++) {
indices[j] += current_size;
}
}
current_size *= 2;
}
return indices;
}

template <class PrecisionT>
auto generatePauliWordData(const std::string &word,
const std::complex<PrecisionT> &coeff)
-> std::vector<std::complex<PrecisionT>> {
constexpr auto IMAG = Pennylane::Util::IMAG<PrecisionT>();
const std::size_t n_word = word.size();
const std::size_t n_data = Pennylane::Util::exp2(n_word);
std::vector<std::complex<PrecisionT>> data(n_data);
std::vector<std::size_t> mtype(n_word);
std::transform(word.begin(), word.end(), mtype.begin(), [](auto ch) {
return (ch == 'I' || ch == 'X') ? 0UL : ((ch == 'Y') ? 1UL : 2UL);
});
std::size_t current_size = 2;
switch (mtype[n_word - 1 - 0]) {
case 0:
data[0] = 1.0;
data[1] = 1.0;
break;
case 1:
data[0] = -IMAG;
data[1] = IMAG;
break;
default:
data[0] = 1.0;
data[1] = -1.0;
break;
}
data[0] *= coeff;
data[1] *= coeff;
for (std::size_t i = 1; i < n_word; i++) {
switch (mtype[n_word - 1 - i]) {
case 0:
std::copy(data.begin(), data.begin() + current_size,
data.begin() + current_size);
break;
case 1:
for (std::size_t j = 0; j < current_size; j++) {
data[j + current_size] = IMAG * data[j];
}
for (std::size_t j = 0; j < current_size; j++) {
data[j] *= -IMAG;
}
break;
default:
for (std::size_t j = 0; j < current_size; j++) {
data[j + current_size] = -data[j];
}
break;
}
current_size *= 2;
}
return data;
}
template std::vector<std::complex<float>>
generatePauliWordData<float>(const std::string &word,
const std::complex<float> &coeff);
template std::vector<std::complex<double>>
generatePauliWordData<double>(const std::string &word,
const std::complex<double> &coeff);

} // namespace Pennylane::LightningQubit::Gates
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@

#include <cstdlib>
#include <set>
#include <string>
#include <utility>
#include <vector>

#include "Util.hpp"
Expand Down Expand Up @@ -84,4 +86,13 @@ struct GateIndices {
external{generateBitPatterns(
getIndicesAfterExclusion(wires, num_qubits), num_qubits)} {}
};

auto generatePauliWordIndices(const std::string &word)
-> std::vector<std::size_t>;

template <class PrecisionT>
auto generatePauliWordData(const std::string &word,
const std::complex<PrecisionT> &coeff)
-> std::vector<std::complex<PrecisionT>>;

} // namespace Pennylane::LightningQubit::Gates
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <algorithm>
#include <bit>
#include <complex>
#include <string>
#include <tuple>
#include <vector>

Expand Down Expand Up @@ -565,23 +566,26 @@ class GateImplementationsLM : public PauliGenerator<GateImplementationsLM> {
}

template <class PrecisionT>
static void applyPauliRot(std::complex<PrecisionT> *arr,
std::size_t num_qubits,
const std::vector<std::size_t> &controlled_wires,
const std::vector<bool> &controlled_values,
const std::vector<std::size_t> &wires,
[[maybe_unused]] const bool inverse,
PrecisionT angle, const std::size_t *indices,
const std::complex<PrecisionT> *data) {
static void
applyPauliRot(std::complex<PrecisionT> *arr, std::size_t num_qubits,
const std::vector<std::size_t> &controlled_wires,
const std::vector<bool> &controlled_values,
const std::vector<std::size_t> &wires, const bool inverse,
PrecisionT angle, const std::string &word) {
constexpr std::size_t one{1};
constexpr auto IMAG = Pennylane::Util::IMAG<PrecisionT>();
const std::size_t n_wires = wires.size();
const std::size_t dim = one << n_wires;
const PrecisionT c = std::cos(angle / 2);
std::vector<std::complex<PrecisionT>> coeffs(dim);
auto core_function = [dim, c, &coeffs, &indices,
const std::complex<PrecisionT> s =
((inverse) ? IMAG : -IMAG) * std::sin(angle / 2);
const auto data = generatePauliWordData(word, s);
const auto indices = generatePauliWordIndices(word);
auto core_function = [dim, c, &indices,
&data](std::complex<PrecisionT> *arr,
const std::vector<std::size_t> &arr_inds,
const std::size_t offset) {
std::vector<std::complex<PrecisionT>> coeffs(dim);
for (std::size_t i = 0; i < dim; i++) {
coeffs[indices[i]] = arr[arr_inds[i] + offset];
}
Expand Down
12 changes: 3 additions & 9 deletions pennylane_lightning/lightning_qubit/_state_vector.py
Original file line number Diff line number Diff line change
Expand Up @@ -318,16 +318,10 @@
)
elif isinstance(operation, qml.PauliRot):
method = getattr(state, "applyPauliRot")
pw = operation._hyperparameters["pauli_word"]
pw = dict((i, w) for i, w in zip(wires, pw) if w != "I")
pw = qml.pauli.PauliWord(pw)
scale = 1.0j if invert_param else -1.0j
scale *= qml.math.sin(operation.parameters[0] / 2)
data = pw._get_csr_data(pw.wires, scale)
indices = pw._get_csr_indices(pw.wires)
word = operation._hyperparameters["pauli_word"]

Check notice on line 321 in pennylane_lightning/lightning_qubit/_state_vector.py

View check run for this annotation

codefactor.io / CodeFactor

pennylane_lightning/lightning_qubit/_state_vector.py#L321

Access to a protected member _hyperparameters of a client class (protected-access)
method(
[], [], pw.wires, False, operation.parameters, indices, data
) # control wires and values
[], [], wires, invert_param, operation.parameters, "".join(word)
) # control wires and values empty
elif method is not None: # apply specialized gate
param = operation.parameters
method(wires, invert_param, param)
Expand Down
Loading