Skip to content

Commit

Permalink
Add wire disjoint check for n-ctrl gate support in LQ (#949)
Browse files Browse the repository at this point in the history
### Before submitting

Please complete the following checklist when submitting a PR:

- [ ] All new features must include a unit test.
If you've fixed a bug or added code that should be tested, add a test to
the
      [`tests`](../tests) directory!

- [ ] All new functions and code must be clearly commented and
documented.
If you do make documentation changes, make sure that the docs build and
      render correctly by running `make docs`.

- [ ] Ensure that the test suite passes, by running `make test`.

- [x] Add a new entry to the `.github/CHANGELOG.md` file, summarizing
the
      change, and including a link back to the PR.

- [x] Ensure that code is properly formatted by running `make format`. 

When all the above are checked, delete everything above the dashed
line and fill in the pull request template.


------------------------------------------------------------------------------------------------------------

**Context:**

[SC-76347]

**Description of the Change:**

**Benefits:**

**Possible Drawbacks:**

**Related GitHub Issues:**

---------

Co-authored-by: ringo-but-quantum <[email protected]>
  • Loading branch information
multiphaseCFD and ringo-but-quantum authored Oct 18, 2024
1 parent c719ac7 commit f36d97c
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 2 deletions.
3 changes: 3 additions & 0 deletions .github/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@

### Improvements

* Add joint check for the N-controlled wires support in `lightning.qubit`.
[(#949)](https://github.com/PennyLaneAI/pennylane-lightning/pull/949)

* Optimize the cartesian product to reduce the amount of memory necessary to set the StatePrep with LightningTensor.
[(#943)](https://github.com/PennyLaneAI/pennylane-lightning/pull/943)

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.39.0-dev46"
__version__ = "0.39.0-dev47"
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,10 @@ class StateVectorLQubit : public StateVectorBase<PrecisionT, Derived> {
const std::vector<std::size_t> &wires,
bool inverse = false,
const std::vector<PrecisionT> &params = {}) {
PL_ABORT_IF_NOT(
areVecsDisjoint<std::size_t>(controlled_wires, wires),
"`controlled_wires` and `target wires` must be disjoint.");

PL_ABORT_IF_NOT(controlled_wires.size() == controlled_values.size(),
"`controlled_wires` must have the same size as "
"`controlled_values`.");
Expand Down Expand Up @@ -420,6 +424,10 @@ class StateVectorLQubit : public StateVectorBase<PrecisionT, Derived> {
const std::vector<std::size_t> &wires, bool inverse,
const std::vector<PrecisionT> &params,
const std::vector<ComplexT, Alloc> &matrix) {
PL_ABORT_IF_NOT(
areVecsDisjoint<std::size_t>(controlled_wires, wires),
"`controlled_wires` and `target wires` must be disjoint.");

PL_ABORT_IF_NOT(controlled_wires.size() == controlled_values.size(),
"`controlled_wires` must have the same size as "
"`controlled_values`.");
Expand Down Expand Up @@ -569,6 +577,9 @@ class StateVectorLQubit : public StateVectorBase<PrecisionT, Derived> {
const std::vector<bool> &controlled_values,
const std::vector<std::size_t> &wires,
bool inverse = false) {
PL_ABORT_IF_NOT(
areVecsDisjoint<std::size_t>(controlled_wires, wires),
"`controlled_wires` and `target wires` must be disjoint.");
applyControlledMatrix(matrix.data(), controlled_wires,
controlled_values, wires, inverse);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -674,6 +674,14 @@ TEMPLATE_TEST_CASE("StateVectorLQubitManaged::applyOperation non-param "
<< "controls = {" << control << "} "
<< ", wires = {" << wire << "} - "
<< PrecisionToName<PrecisionT>::value) {
if (control == wire) {
REQUIRE_THROWS_AS(
sv0.applyOperation("PauliX", std::vector<std::size_t>{control},
std::vector<bool>{true},
std::vector<std::size_t>{wire}),
LightningException);
}

if (control != wire) {
auto st0 = createRandomStateVectorData<PrecisionT>(re, num_qubits);
sv0.updateData(st0);
Expand All @@ -687,7 +695,7 @@ TEMPLATE_TEST_CASE("StateVectorLQubitManaged::applyOperation non-param "
approx(sv1.getDataVector()).margin(margin));
}

if (control != 0 && wire != 0) {
if (control != 0 && wire != 0 && control != wire) {
sv0.applyOperation("Toffoli", {0, control, wire});
sv1.applyOperation("PauliX", std::vector<std::size_t>{0, control},
std::vector<bool>{true, true},
Expand Down Expand Up @@ -760,6 +768,15 @@ TEMPLATE_TEST_CASE("StateVectorLQubitManaged::applyOperation non-param "
REQUIRE(sv0.getDataVector() ==
approx(sv1.getDataVector()).margin(margin));
}

if (control == wire) {
const auto matrix = getHadamard<std::complex, PrecisionT>();
REQUIRE_THROWS_AS(sv0.applyControlledMatrix(
matrix, std::vector<std::size_t>{control},
std::vector<bool>{true},
std::vector<std::size_t>{wire}),
LightningException);
}
}
DYNAMIC_SECTION("N-controlled S - "
<< "controls = {" << control << "} "
Expand Down
18 changes: 18 additions & 0 deletions pennylane_lightning/core/src/utils/Util.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -574,4 +574,22 @@ std::vector<T1> cast_vector(const std::vector<T0> &vec) {
return result;
}

/**
* @brief Check if two vectors are disjoint.
* @tparam T Data type.
* @param v1 First vector.
* @param v2 Second vector.
*
* @return bool True if the vectors are disjoint, false otherwise.
*/
template <typename T = std::size_t>
bool areVecsDisjoint(const std::vector<T> &v1, const std::vector<T> &v2) {
std::set<T> s0(v1.begin(), v1.end());
for (const auto &element : v2) {
if (s0.find(element) != s0.end()) {
return false;
}
}
return true;
}
} // namespace Pennylane::Util
16 changes: 16 additions & 0 deletions pennylane_lightning/core/src/utils/tests/Test_Util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -217,3 +217,19 @@ TEMPLATE_TEST_CASE("Util::kronProd", "[Util][LinearAlgebra]", float, double) {
CHECK(vec == expected);
}
}

TEST_CASE("Util::areVecsDisjoint", "[Util][LinearAlgebra]") {
SECTION("Test for disjoint vectors") {
std::vector<std::size_t> vec0{0, 1, 2};
std::vector<std::size_t> vec1{3, 4, 5};

REQUIRE(areVecsDisjoint(vec0, vec1) == true);
}

SECTION("Test for joint vectors") {
std::vector<std::size_t> vec0{0, 1, 2};
std::vector<std::size_t> vec1{2, 4, 5};

REQUIRE(areVecsDisjoint(vec0, vec1) == false);
}
}

0 comments on commit f36d97c

Please sign in to comment.