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

Allow lightning.qubit/kokkos::generate_samples to take in seeds to make the generated samples deterministic #927

Merged
merged 39 commits into from
Oct 3, 2024
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
290a497
try getting catalyst's rng for generating samples
paul0403 Sep 30, 2024
133bc29
set default to nullptr
paul0403 Sep 30, 2024
d0f0777
Auto update version from '0.39.0-dev33' to '0.39.0-dev34'
ringo-but-quantum Sep 30, 2024
ea8290b
make the other `generate_samples` take in the rng as well
paul0403 Sep 30, 2024
ce4c532
undo kokkos changes for now
paul0403 Sep 30, 2024
9e5eb33
remove unnecessary `this->`
paul0403 Sep 30, 2024
6aa6d47
passing pointers as const reference
paul0403 Sep 30, 2024
cfb16b4
format
paul0403 Sep 30, 2024
3047599
convert to std::optional to avoid (pointers + default value of nullptr);
paul0403 Sep 30, 2024
0b943f1
give std::nullopt default to std::optional
paul0403 Sep 30, 2024
f496df8
test
paul0403 Oct 1, 2024
e116f5c
Auto update version from '0.39.0-dev34' to '0.39.0-dev35'
ringo-but-quantum Oct 1, 2024
3c52db6
Merge remote-tracking branch 'origin/master' into seed_sample_lightning
paul0403 Oct 1, 2024
5216cca
apply clang tidy comments
paul0403 Oct 1, 2024
234ced7
format
paul0403 Oct 1, 2024
c4c5341
pass the seeding integer, instead of the rng instance; add kokkos
paul0403 Oct 1, 2024
2a2420e
codefactor
paul0403 Oct 1, 2024
671fed4
debug push
paul0403 Oct 1, 2024
1f861df
debug
paul0403 Oct 1, 2024
3624cb0
remove debug prints
paul0403 Oct 2, 2024
5896119
small comments
paul0403 Oct 2, 2024
b2e3759
changelog
paul0403 Oct 2, 2024
9e98e33
changelog author
paul0403 Oct 2, 2024
e57ada4
`auto` for kokkos random pool type when type is obvious;
paul0403 Oct 2, 2024
f082ea1
catalyst kokkos seed sample test
paul0403 Oct 2, 2024
5edfdfa
format
paul0403 Oct 2, 2024
3fca3d4
Auto update version from '0.39.0-dev35' to '0.39.0-dev36'
ringo-but-quantum Oct 2, 2024
c2f8e1a
Merge remote-tracking branch 'origin/master' into seed_sample_lightning
paul0403 Oct 2, 2024
5101ff4
change helper to private
paul0403 Oct 2, 2024
a127f33
fix lightning.gpu test failure
paul0403 Oct 2, 2024
c70de5d
optional header
paul0403 Oct 2, 2024
82a3ed0
Merge remote-tracking branch 'origin/master' into seed_sample_lightning
paul0403 Oct 3, 2024
3be52d6
factor out common furnitures for all loop iterations for kokkos catal…
paul0403 Oct 3, 2024
92b64f7
remove const for size_t
paul0403 Oct 3, 2024
edfa8fd
rewrite the measurement seeding kokkos test to reuse common furniture…
paul0403 Oct 3, 2024
5306829
Auto update version from '0.39.0-dev36' to '0.39.0-dev37'
ringo-but-quantum Oct 3, 2024
ddc6732
small bug
paul0403 Oct 3, 2024
3362dd0
Merge remote-tracking branch 'origin/master' into seed_sample_lightning
paul0403 Oct 3, 2024
c4d67f4
Auto update version from '0.39.0-dev37' to '0.39.0-dev38'
ringo-but-quantum Oct 3, 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.39.0-dev34"
__version__ = "0.39.0-dev35"
paul0403 marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,19 @@ template <class StateVectorT, class Derived> class MeasurementsBase {
/**
* @brief Randomly set the seed of the internal random generator
*
* @param seed Seed
*/
void setRandomSeed() {
std::random_device rd;
setSeed(rd());
}

/**
* @brief Set the internal random generator to an already existing instance
*
* @param rng An already existing instance of a random number generator
*/
void setRNG(std::mt19937 rng) { this->rng = rng; }
paul0403 marked this conversation as resolved.
Show resolved Hide resolved

/**
* @brief Calculate the expectation value for a general Observable.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ using Pennylane::Util::isApproxEqual;
} // namespace
/// @endcond
#include <algorithm>
#include <optional>
#include <random>
paul0403 marked this conversation as resolved.
Show resolved Hide resolved
#include <string>

#ifdef _ENABLE_PLQUBIT
Expand Down Expand Up @@ -1251,7 +1253,9 @@ TEST_CASE("Var Shot- TensorProdObs", "[MeasurementsBase][Observables]") {
testTensorProdObsVarShot<TestStateVectorBackends>();
}
}
template <typename TypeList> void testSamples() {

template <typename TypeList>
void testSamples(const std::optional<std::mt19937> &rng = std::nullopt) {
if constexpr (!std::is_same_v<TypeList, void>) {
using StateVectorT = typename TypeList::Type;
using PrecisionT = typename StateVectorT::PrecisionT;
Expand Down Expand Up @@ -1281,7 +1285,10 @@ template <typename TypeList> void testSamples() {
std::size_t num_qubits = 3;
std::size_t N = std::pow(2, num_qubits);
std::size_t num_samples = 100000;
auto &&samples = Measurer.generate_samples(num_samples);
auto &&samples =
rng.has_value()
? Measurer.generate_samples(num_samples, rng.value())
: Measurer.generate_samples(num_samples);

std::vector<std::size_t> counts(N, 0);
std::vector<std::size_t> samples_decimal(num_samples, 0);
Expand All @@ -1307,7 +1314,7 @@ template <typename TypeList> void testSamples() {
REQUIRE_THAT(probabilities,
Catch::Approx(expected_probabilities).margin(.05));
}
testSamples<typename TypeList::Next>();
testSamples<typename TypeList::Next>(rng);
}
}

Expand All @@ -1317,6 +1324,13 @@ TEST_CASE("Samples", "[MeasurementsBase]") {
}
}

TEST_CASE("Seeded samples", "[MeasurementsBase]") {
if constexpr (BACKEND_FOUND) {
std::mt19937 rng(37);
testSamples<TestStateVectorBackends>(rng);
}
}

template <typename TypeList> void testSamplesCountsObs() {
if constexpr (!std::is_same_v<TypeList, void>) {
using StateVectorT = typename TypeList::Type;
Expand Down Expand Up @@ -1729,4 +1743,4 @@ TEST_CASE("Measure Shot - SparseHObs ", "[MeasurementsBase][Observables]") {
if constexpr (BACKEND_FOUND) {
testSparseHObsMeasureShot<TestStateVectorBackends>();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <algorithm>
#include <complex>
#include <cstdio>
#include <optional>
#include <random>
#include <type_traits>
#include <unordered_map>
Expand Down Expand Up @@ -573,30 +574,38 @@ class Measurements final
* Reference: https://en.wikipedia.org/wiki/Alias_method
*
* @param num_samples The number of samples to generate.
* @param catalyst_rng The seeded random number generator from catalyst.
* @return 1-D vector of samples in binary, each sample is
* separated by a stride equal to the number of qubits.
*/
std::vector<std::size_t> generate_samples(const std::size_t num_samples) {
std::vector<std::size_t> generate_samples(
const std::size_t num_samples,
const std::optional<std::mt19937> &catalyst_rng = std::nullopt) {
const std::size_t num_qubits = this->_statevector.getNumQubits();
std::vector<std::size_t> wires(num_qubits);
std::iota(wires.begin(), wires.end(), 0);
return generate_samples(wires, num_samples);
return generate_samples(wires, num_samples, catalyst_rng);
}

/**
* @brief Generate samples.
*
* @param wires Sample are generated for the specified wires.
* @param num_samples The number of samples to generate.
* @param catalyst_rng The seeded random number generator from catalyst.
* @return 1-D vector of samples in binary, each sample is
* separated by a stride equal to the number of qubits.
*/
std::vector<std::size_t>
generate_samples(const std::vector<std::size_t> &wires,
const std::size_t num_samples) {
std::vector<std::size_t> generate_samples(
const std::vector<std::size_t> &wires, const std::size_t num_samples,
const std::optional<std::mt19937> &catalyst_rng = std::nullopt) {
const std::size_t n_wires = wires.size();
std::vector<std::size_t> samples(num_samples * n_wires);
this->setRandomSeed();
if (catalyst_rng.has_value()) {
this->setRNG(catalyst_rng.value());
paul0403 marked this conversation as resolved.
Show resolved Hide resolved
} else {
this->setRandomSeed();
}
DiscreteRandomVariable<PrecisionT> drv{this->rng, probs(wires)};
// The Python layer expects a 2D array with dimensions (n_samples x
// n_wires) and hence the linear index is `s * n_wires + (n_wires - 1 -
Expand Down
Loading