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 MidMeasureMP Kokkos #658

Merged
merged 35 commits into from
Apr 12, 2024
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
174addc
collapse() and normalized() with Kokkos
tomlqc Mar 8, 2024
6da13fb
Auto update version
github-actions[bot] Mar 21, 2024
4cecf3e
CodeFactor
tomlqc Mar 21, 2024
e54f06f
normalize() abort if norm is zero
tomlqc Mar 21, 2024
6c2bb9d
unittest for normalize()
tomlqc Mar 21, 2024
e06ded6
Auto update version
github-actions[bot] Mar 21, 2024
694a62c
unittest for normalize() in LighningQubit
tomlqc Mar 21, 2024
30e51b9
Merge remote-tracking branch 'origin/master' into feature/mid-measure…
vincentmr Apr 4, 2024
31bc86f
Auto update version
github-actions[bot] Apr 4, 2024
3f3ab86
Add MCM bindings and tests for L-Kokkos. (#672)
vincentmr Apr 10, 2024
4bff4e5
Merge branch 'master' into feature/mid-measure-kokkos
vincentmr Apr 10, 2024
8e4030b
Do not run test_native_mcm with LK-GPU.
vincentmr Apr 10, 2024
d454a57
Merge branch 'master' into feature/mid-measure-kokkos
vincentmr Apr 10, 2024
dff080a
Auto update version
github-actions[bot] Apr 10, 2024
2e2a146
trigger ci
vincentmr Apr 10, 2024
a9564a4
Update pennylane_lightning/core/src/simulators/lightning_kokkos/bindi…
vincentmr Apr 12, 2024
6996858
Auto update version
github-actions[bot] Apr 12, 2024
5ac112c
Merge branch 'master' into feature/mid-measure-kokkos
vincentmr Apr 12, 2024
fb35dd2
Update pennylane_lightning/core/src/simulators/lightning_kokkos/State…
vincentmr Apr 12, 2024
b551e19
Update pennylane_lightning/core/src/simulators/lightning_kokkos/State…
vincentmr Apr 12, 2024
b236550
Update pennylane_lightning/core/src/simulators/lightning_kokkos/State…
vincentmr Apr 12, 2024
be8a264
Update pennylane_lightning/core/src/simulators/lightning_kokkos/State…
vincentmr Apr 12, 2024
dc7ddd5
Increase shotsfor flaky test_composite_mcm_single_measure_obs
vincentmr Apr 12, 2024
2395097
Create separate device_allowed_operations list for ops supported by t…
vincentmr Apr 12, 2024
fbba18a
Use isinstance instead of name comparison.
vincentmr Apr 12, 2024
e5c2a8e
Check projector.
vincentmr Apr 12, 2024
e5fd200
Update operations at device init.
vincentmr Apr 12, 2024
193a279
Modify stopping condition in LK.
vincentmr Apr 12, 2024
84ea17b
Cannot use instance with Hamiltonian check.
vincentmr Apr 12, 2024
dc5d848
Update pennylane_lightning/core/src/simulators/lightning_kokkos/tests…
vincentmr Apr 12, 2024
098ca7e
Update pennylane_lightning/core/src/simulators/lightning_kokkos/State…
vincentmr Apr 12, 2024
121d403
Remove obsolete comment.
vincentmr Apr 12, 2024
f2f3e33
Merge branch 'master' into feature/mid-measure-kokkos
vincentmr Apr 12, 2024
bfc7b6c
Auto update version
github-actions[bot] Apr 12, 2024
e4f0716
trigger ci
vincentmr Apr 12, 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
2 changes: 1 addition & 1 deletion pennylane_lightning/core/_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@
Version number (major.minor.patch[-label])
"""

__version__ = "0.36.0-dev14"
__version__ = "0.36.0-dev16"
Original file line number Diff line number Diff line change
Expand Up @@ -757,6 +757,60 @@ class StateVectorKokkos final
return -static_cast<fp_t>(0.5);
}

/**
* @brief Collapse the state vector as after having measured one of the
* qubits.
vincentmr marked this conversation as resolved.
Show resolved Hide resolved
*
* The branch parameter imposes the measurement result on the given wire.
*
* @param wire Wire to collapse.
* @param branch Branch 0 or 1.
*/
void collapse(const std::size_t wire, const bool branch) {
vincentmr marked this conversation as resolved.
Show resolved Hide resolved
auto &&num_qubits = this->getNumQubits();

const size_t stride = pow(2, num_qubits_ - (1 + wire));
const size_t vec_size = pow(2, num_qubits_);
const auto section_size = vec_size / stride;
const auto half_section_size = section_size / 2;

const size_t negbranch = branch ? 0 : 1;

Kokkos::MDRangePolicy<DoubleLoopRank> policy_2d(
{0, 0}, {half_section_size, stride});
Kokkos::parallel_for(
policy_2d,
collapseFunctor<fp_t>(*data_, num_qubits, stride, negbranch));

normalize();
}

/**
* @brief Normalize vector (to have norm 1).
*/
void normalize() {
KokkosVector sv_view =
getView(); // circumvent error capturing this with KOKKOS_LAMBDA

// TODO: @tomlqc what about squaredNorm()
vincentmr marked this conversation as resolved.
Show resolved Hide resolved
PrecisionT squaredNorm = 0.0;
Kokkos::parallel_reduce(
sv_view.size(),
KOKKOS_LAMBDA(const size_t i, PrecisionT &sum) {
sum += std::norm<PrecisionT>(sv_view(i));
vincentmr marked this conversation as resolved.
Show resolved Hide resolved
},
squaredNorm);

PL_ABORT_IF(squaredNorm <
std::numeric_limits<PrecisionT>::epsilon() * 1e2,
"vector has norm close to zero and can't be normalized");

std::complex<PrecisionT> inv_norm = 1. / std::sqrt(squaredNorm);
vincentmr marked this conversation as resolved.
Show resolved Hide resolved
Kokkos::parallel_for(
sv_view.size(),
KOKKOS_LAMBDA(const size_t i) { sv_view(i) *= inv_norm; });
}

/**
* @brief Update data of the class
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -972,4 +972,35 @@ template <class PrecisionT, bool adj = false> struct generatorMultiRZFunctor {
1 - 2 * int(Kokkos::Impl::bit_count(k & wires_parity) % 2));
}
};

template <class PrecisionT> struct collapseFunctor {
vincentmr marked this conversation as resolved.
Show resolved Hide resolved
using ComplexT = Kokkos::complex<PrecisionT>;
using KokkosComplexVector = Kokkos::View<ComplexT *>;

KokkosComplexVector arr;
std::size_t num_qubits;
std::size_t stride;
std::size_t negbranch;

collapseFunctor(KokkosComplexVector &arr_, std::size_t num_qubits_,
std::size_t stride_, std::size_t negbranch_) {
arr = arr_;
num_qubits = num_qubits_;
stride = stride_;
negbranch = negbranch_;
}

// zero half the entries
// the "half" entries depend on the stride
// *_*_*_*_ for stride 1
// **__**__ for stride 2
// ****____ for stride 4

KOKKOS_INLINE_FUNCTION
void operator()(const std::size_t left, const std::size_t right) const {
const size_t offset = stride * (negbranch + 2 * left);
arr[offset + right] = ComplexT{0., 0.};
}
};

} // namespace Pennylane::LightningKokkos::Functors
Original file line number Diff line number Diff line change
Expand Up @@ -308,4 +308,72 @@ TEMPLATE_TEST_CASE("StateVectorKokkos::StateVectorKokkos",
REQUIRE(sv.getDataVector() == data_);
// REQUIRE(sv.getDataVector() == approx(st_data));
}
}
}

TEMPLATE_TEST_CASE("StateVectorKokkos::collapse", "[StateVectorKokkos]", float,
double) {
using PrecisionT = TestType;
using ComplexT = typename StateVectorKokkos<PrecisionT>::ComplexT;
using TestVectorT = TestVector<ComplexT>;

const std::size_t num_qubits = 3;

// TODO @tomlqc use same template for testing all Lightning flavours?

SECTION("Collapse the state vector as after having measured one of the "
vincentmr marked this conversation as resolved.
Show resolved Hide resolved
"qubits.") {
TestVectorT init_state = createPlusState_<ComplexT>(num_qubits);

const ComplexT coef{0.5, PrecisionT{0.0}};
const ComplexT zero{PrecisionT{0.0}, PrecisionT{0.0}};

std::vector<std::vector<std::vector<ComplexT>>> expected_state = {
{{coef, coef, coef, coef, zero, zero, zero, zero},
{coef, coef, zero, zero, coef, coef, zero, zero},
{coef, zero, coef, zero, coef, zero, coef, zero}},
{{zero, zero, zero, zero, coef, coef, coef, coef},
{zero, zero, coef, coef, zero, zero, coef, coef},
{zero, coef, zero, coef, zero, coef, zero, coef}},
};

std::size_t wire = GENERATE(0, 1, 2);
std::size_t branch = GENERATE(0, 1);
StateVectorKokkos<PrecisionT> sv(
reinterpret_cast<ComplexT *>(init_state.data()), init_state.size());
sv.collapse(wire, branch);

PrecisionT eps = std::numeric_limits<PrecisionT>::epsilon() * 10e3;
REQUIRE(isApproxEqual(sv.getData(), sv.getDataVector().size(),
expected_state[branch][wire].data(),
expected_state[branch][wire].size(), eps));
}
}

TEMPLATE_TEST_CASE("StateVectorKokkos::normalize", "[StateVectorKokkos]", float,
double) {
using PrecisionT = TestType;
using ComplexT = typename StateVectorKokkos<PrecisionT>::ComplexT;

// TODO @tomlqc use same template for testing all Lightning flavours?
vincentmr marked this conversation as resolved.
Show resolved Hide resolved

SECTION("Normalize state vector.") {
const ComplexT init{1.0, PrecisionT{0.0}};
const ComplexT half{0.5, PrecisionT{0.0}};
const ComplexT zero{PrecisionT{0.0}, PrecisionT{0.0}};

std::vector<ComplexT> init_state = {init, zero, init, init,
zero, zero, init, zero};

std::vector<ComplexT> expected_state = {half, zero, half, half,
zero, zero, half, zero};

StateVectorKokkos<PrecisionT> sv(
reinterpret_cast<ComplexT *>(init_state.data()), init_state.size());
sv.normalize();

PrecisionT eps = std::numeric_limits<PrecisionT>::epsilon() * 1e3;
REQUIRE(isApproxEqual(sv.getData(), sv.getDataVector().size(),
expected_state.data(), expected_state.size(),
eps));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -245,9 +245,35 @@ TEMPLATE_PRODUCT_TEST_CASE("StateVectorLQubit::collapse", "[StateVectorLQubit]",

std::size_t wire = GENERATE(0, 1, 2);
std::size_t branch = GENERATE(0, 1);
StateVectorLQubitManaged<PrecisionT> sv(init_state);
StateVectorT sv(init_state.data(), init_state.size());
sv.collapse(wire, branch);

REQUIRE(sv.getDataVector() == approx(expected_state[branch][wire]));
}
}

TEMPLATE_PRODUCT_TEST_CASE("StateVectorLQubit::normalize",
"[StateVectorLQubit]",
(StateVectorLQubitManaged, StateVectorLQubitRaw),
(float, double)) {
using StateVectorT = TestType;
using PrecisionT = typename StateVectorT::PrecisionT;
using ComplexT = typename StateVectorT::ComplexT;

SECTION("Normalize state vector.") {
const ComplexT init{1.0, PrecisionT{0.0}};
const ComplexT half{0.5, PrecisionT{0.0}};
const ComplexT zero{PrecisionT{0.0}, PrecisionT{0.0}};

std::vector<ComplexT> init_state = {init, zero, init, init,
zero, zero, init, zero};

std::vector<ComplexT> expected_state = {half, zero, half, half,
zero, zero, half, zero};

StateVectorT sv(init_state.data(), init_state.size());
sv.normalize();

REQUIRE(sv.getDataVector() == approx(expected_state));
}
}
13 changes: 13 additions & 0 deletions pennylane_lightning/core/src/utils/TestHelpers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,19 @@ auto createZeroState(size_t num_qubits) -> TestVector<ComplexT> {
return res;
}

/**
* @brief create |+>^N
*/
template <typename ComplexT>
auto createPlusState_(size_t num_qubits) -> TestVector<ComplexT> {
vincentmr marked this conversation as resolved.
Show resolved Hide resolved
TestVector<ComplexT> res(size_t{1U} << num_qubits, 1.0,
getBestAllocator<ComplexT>());
for (auto &elem : res) {
elem /= std::sqrt(1U << num_qubits);
}
return res;
}

/**
* @brief create |+>^N
*/
Expand Down