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 all 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
3 changes: 3 additions & 0 deletions .github/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

### New features since last release

* `lightning.kokkos` supports mid-circuit measurements.
[(#672)](https://github.com/PennyLaneAI/pennylane-lightning/pull/672)

* Add dynamic linking to LAPACK/OpenBlas shared objects in scipy.libs for both C++ and Python layer.
[(#653)](https://github.com/PennyLaneAI/pennylane-lightning/pull/653)

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/tests_gpu_cuda.yml
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ jobs:
OMP_PROC_BIND: false
run: |
cd main/
PL_DEVICE=lightning.qubit python -m pytest tests/ $COVERAGE_FLAGS
PL_DEVICE=lightning.qubit python -m pytest tests/ -k "not test_native_mcm" $COVERAGE_FLAGS
vincentmr marked this conversation as resolved.
Show resolved Hide resolved
pl-device-test --device lightning.qubit --skip-ops --shots=20000 $COVERAGE_FLAGS --cov-append
pl-device-test --device lightning.qubit --shots=None --skip-ops $COVERAGE_FLAGS --cov-append
PL_DEVICE=lightning.gpu python -m pytest tests/ $COVERAGE_FLAGS
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/tests_gpu_kokkos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -303,9 +303,9 @@ jobs:
run: |
cd main/
DEVICENAME=`echo ${{ matrix.pl_backend }} | sed "s/_/./g"`
PL_DEVICE=${DEVICENAME} python -m pytest tests/ -k "not test_native_mcm" $COVERAGE_FLAGS 2> /dev/null || echo Something went wrong with Pytest
pl-device-test --device ${DEVICENAME} --skip-ops --shots=20000 $COVERAGE_FLAGS --cov-append 2> /dev/null || echo Something went wrong with pl-device-test shot=20000
pl-device-test --device ${DEVICENAME} --shots=None --skip-ops $COVERAGE_FLAGS --cov-append 2> /dev/null || echo Something went wrong with pl-device-test shot=None
PL_DEVICE=${DEVICENAME} python -m pytest tests/ $COVERAGE_FLAGS 2> /dev/null || echo Something went wrong with Pytest
mv coverage.xml coverage-${{ github.job }}-${{ matrix.pl_backend }}.xml

- name: Install all backend devices
Expand All @@ -325,10 +325,10 @@ jobs:
OMP_PROC_BIND: false
run: |
cd main/
PL_DEVICE=lightning.qubit python -m pytest tests/ $COVERAGE_FLAGS
PL_DEVICE=lightning.qubit python -m pytest tests/ -k "not test_native_mcm" $COVERAGE_FLAGS
vincentmr marked this conversation as resolved.
Show resolved Hide resolved
pl-device-test --device lightning.qubit --skip-ops --shots=20000 $COVERAGE_FLAGS --cov-append
pl-device-test --device lightning.qubit --shots=None --skip-ops $COVERAGE_FLAGS --cov-append
PL_DEVICE=lightning.kokkos python -m pytest tests/ $COVERAGE_FLAGS
PL_DEVICE=lightning.kokkos python -m pytest tests/ -k "not test_native_mcm" $COVERAGE_FLAGS --cov-append
pl-device-test --device lightning.kokkos --skip-ops --shots=20000 $COVERAGE_FLAGS --cov-append
pl-device-test --device lightning.kokkos --shots=None --skip-ops $COVERAGE_FLAGS --cov-append
mv coverage.xml coverage-${{ github.job }}-${{ matrix.pl_backend }}.xml
Expand Down
14 changes: 8 additions & 6 deletions .github/workflows/tests_linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ env:
COVERAGE_FLAGS: "--cov=pennylane_lightning --cov-report=term-missing --no-flaky-report -p no:warnings --tb=native"
GCC_VERSION: 11
OMP_NUM_THREADS: "2"
OMP_PROC_BIND: "false"

concurrency:
group: tests_linux-${{ github.ref }}-${{ inputs.lightning-version }}-${{ inputs.pennylane-version }}
Expand Down Expand Up @@ -353,8 +354,8 @@ jobs:
python -m pip install pytest-xdist
cd main/
DEVICENAME=`echo ${{ matrix.pl_backend }} | sed "s/_/./g"`
OMP_NUM_THREADS=1 PL_DEVICE=${DEVICENAME} python -m pytest -n auto tests/ -k "not unitary_correct" $COVERAGE_FLAGS
PL_DEVICE=${DEVICENAME} python -m pytest tests/ -k "unitary_correct" $COVERAGE_FLAGS --cov-append
OMP_NUM_THREADS=1 PL_DEVICE=${DEVICENAME} python -m pytest -n auto tests/ -k "not unitary_correct and not test_native_mcm" $COVERAGE_FLAGS
vincentmr marked this conversation as resolved.
Show resolved Hide resolved
PL_DEVICE=${DEVICENAME} python -m pytest tests/ -k "unitary_correct and not test_native_mcm" $COVERAGE_FLAGS --cov-append
pl-device-test --device ${DEVICENAME} --skip-ops --shots=20000 $COVERAGE_FLAGS --cov-append
pl-device-test --device ${DEVICENAME} --shots=None --skip-ops $COVERAGE_FLAGS --cov-append
mv .coverage .coverage-${{ github.job }}-${{ matrix.pl_backend }}
Expand Down Expand Up @@ -558,7 +559,8 @@ jobs:
python -m pip install pytest-xdist
cd main/
DEVICENAME=`echo ${{ matrix.pl_backend }} | sed "s/_/./g"`
PL_DEVICE=${DEVICENAME} python -m pytest tests/ $COVERAGE_FLAGS
PL_DEVICE=${DEVICENAME} python -m pytest tests/ -k "not test_native_mcm" $COVERAGE_FLAGS
OMP_NUM_THREADS=1 PL_DEVICE=${DEVICENAME} python -m pytest -n auto tests/ -k "test_native_mcm" $COVERAGE_FLAGS --cov-append
pl-device-test --device ${DEVICENAME} --skip-ops --shots=20000 $COVERAGE_FLAGS --cov-append
pl-device-test --device ${DEVICENAME} --shots=None --skip-ops $COVERAGE_FLAGS --cov-append
mv .coverage .coverage-${{ github.job }}-${{ matrix.pl_backend }}
Expand All @@ -579,11 +581,11 @@ jobs:
# TODO: Remove installing pytest-xdist with release v0.36.0
python -m pip install pytest-xdist
cd main/
OMP_NUM_THREADS=1 PL_DEVICE=lightning.qubit python -m pytest -n auto tests/ -k "not unitary_correct" $COVERAGE_FLAGS
PL_DEVICE=lightning.qubit python -m pytest tests/ -k "unitary_correct" $COVERAGE_FLAGS --cov-append
OMP_NUM_THREADS=1 PL_DEVICE=lightning.qubit python -m pytest -n auto tests/ -k "not unitary_correct and not test_native_mcm" $COVERAGE_FLAGS
PL_DEVICE=lightning.qubit python -m pytest tests/ -k "unitary_correct and not test_native_mcm" $COVERAGE_FLAGS --cov-append
pl-device-test --device lightning.qubit --skip-ops --shots=20000 $COVERAGE_FLAGS --cov-append
pl-device-test --device lightning.qubit --shots=None --skip-ops $COVERAGE_FLAGS --cov-append
PL_DEVICE=lightning.kokkos python -m pytest tests/ $COVERAGE_FLAGS --cov-append
PL_DEVICE=lightning.kokkos python -m pytest tests/ -k "not test_native_mcm" $COVERAGE_FLAGS --cov-append
pl-device-test --device lightning.kokkos --skip-ops --shots=20000 $COVERAGE_FLAGS --cov-append
pl-device-test --device lightning.kokkos --shots=None --skip-ops $COVERAGE_FLAGS --cov-append
mv .coverage .coverage-${{ github.job }}-${{ matrix.pl_backend }}
Expand Down
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-dev27"
__version__ = "0.36.0-dev28"
4 changes: 2 additions & 2 deletions pennylane_lightning/core/lightning_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,9 @@
and observable) and returns ``True`` if supported by the device."""

def accepts_obj(obj):
if obj.name == "QFT":
if isinstance(obj, qml.QFT):

Check warning on line 97 in pennylane_lightning/core/lightning_base.py

View check run for this annotation

Codecov / codecov/patch

pennylane_lightning/core/lightning_base.py#L97

Added line #L97 was not covered by tests
return len(obj.wires) < 10
if obj.name == "GroverOperator":
if isinstance(obj, qml.GroverOperator):

Check warning on line 99 in pennylane_lightning/core/lightning_base.py

View check run for this annotation

Codecov / codecov/patch

pennylane_lightning/core/lightning_base.py#L99

Added line #L99 was not covered by tests
return len(obj.wires) < 13
is_not_tape = not isinstance(obj, qml.tape.QuantumTape)
is_supported = getattr(self, "supports_operation", lambda name: False)(obj.name)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -757,6 +757,53 @@ class StateVectorKokkos final
return -static_cast<fp_t>(0.5);
}

/**
* @brief Collapse the state vector after having measured one of the
* qubits.
*
* The branch parameter imposes the measurement result on the given wire.
*
* @param wire Wire to collapse.
* @param branch Branch 0 or 1.
*/
void collapse(std::size_t wire, bool branch) {
KokkosVector matrix("gate_matrix", 4);
Kokkos::parallel_for(
matrix.size(), KOKKOS_LAMBDA(std::size_t k) {
matrix(k) = ((k == 0 && branch == 0) || (k == 3 && branch == 1))
? ComplexT{1.0, 0.0}
: ComplexT{0.0, 0.0};
});
applyMultiQubitOp(matrix, {wire}, false);
normalize();
}

/**
* @brief Normalize vector (to have norm 1).
*/
void normalize() {
auto sv_view = getView();

PrecisionT squaredNorm = 0.0;
Kokkos::parallel_reduce(
sv_view.size(),
KOKKOS_LAMBDA(std::size_t i, PrecisionT & sum) {
const PrecisionT norm = Kokkos::abs(sv_view(i));
sum += norm * norm;
},
squaredNorm);

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

const std::complex<PrecisionT> inv_norm =
1. / Kokkos::sqrt(squaredNorm);
Kokkos::parallel_for(
sv_view.size(),
KOKKOS_LAMBDA(std::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 @@ -137,7 +137,11 @@ void registerBackendClassSpecificBindings(PyClass &pyclass) {
sv.applyOperation(str, wires, inv, std::vector<ParamT>{},
conv_matrix);
},
"Apply operation via the gate matrix");
"Apply operation via the gate matrix")
.def("collapse", &StateVectorT::collapse,
"Collapse the statevector onto the 0 or 1 branch of a given wire.")
.def("normalize", &StateVectorT::normalize,
"Normalize the statevector to norm 1.");
}

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

} // namespace Pennylane::LightningKokkos::Functors
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <chrono>

#include <Kokkos_Core.hpp>
#include <Kokkos_Random.hpp>
Expand Down Expand Up @@ -682,7 +683,10 @@ class Measurements final
});

// Sampling using Random_XorShift64_Pool
Kokkos::Random_XorShift64_Pool<> rand_pool(5374857);
Kokkos::Random_XorShift64_Pool<> rand_pool(
vincentmr marked this conversation as resolved.
Show resolved Hide resolved
std::chrono::high_resolution_clock::now()
.time_since_epoch()
.count());

Kokkos::parallel_for(
Kokkos::RangePolicy<KokkosExecSpace>(0, num_samples),
Expand Down
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 after having measured one of the "
"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;

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

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
Loading
Loading