Skip to content

Commit

Permalink
Remove maps in SVKokkos (#641)
Browse files Browse the repository at this point in the history
* Simplify map init in SVKokkos

* Auto update version

* Update changelog

* Add flaky marker to test_double_return_value

* const var in loop

* Auto update version

* trigger ci

* Add a couple routine to use Constant array directly.

* Auto update version

* trigger ci

---------

Co-authored-by: Dev version update bot <github-actions[bot]@users.noreply.github.com>
  • Loading branch information
vincentmr and github-actions[bot] authored Mar 14, 2024
1 parent 5e750d2 commit 6c758e4
Show file tree
Hide file tree
Showing 13 changed files with 99 additions and 137 deletions.
3 changes: 3 additions & 0 deletions .github/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@

### Improvements

* Initialize the private attributes `gates_indices_` and `generators_indices_` of `StateVectorKokkos` using the definitions of the `Pennylane::Gates::Constant` namespace.
[(#641)](https://github.com/PennyLaneAI/pennylane-lightning/pull/641)

* Add `isort` to `requirements-dev.txt` and run before `black` upon `make format` to sort Python imports.
[(#623)](https://github.com/PennyLaneAI/pennylane-lightning/pull/623)

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-dev7"
__version__ = "0.36.0-dev8"
44 changes: 20 additions & 24 deletions pennylane_lightning/core/src/gates/Constant.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,38 +121,34 @@ using CGateView = typename std::pair<ControlledGateOperation, std::string_view>;
/**
* @brief Generator names.
*
* Note that a name of generators must be "Generator" +
* the name of the corresponding gate.
*/
using GeneratorView = typename std::pair<GeneratorOperation, std::string_view>;
[[maybe_unused]] constexpr std::array generator_names = {
GeneratorView{GeneratorOperation::PhaseShift, "GeneratorPhaseShift"},
GeneratorView{GeneratorOperation::RX, "GeneratorRX"},
GeneratorView{GeneratorOperation::RY, "GeneratorRY"},
GeneratorView{GeneratorOperation::RZ, "GeneratorRZ"},
GeneratorView{GeneratorOperation::CRX, "GeneratorCRX"},
GeneratorView{GeneratorOperation::CRY, "GeneratorCRY"},
GeneratorView{GeneratorOperation::CRZ, "GeneratorCRZ"},
GeneratorView{GeneratorOperation::IsingXX, "GeneratorIsingXX"},
GeneratorView{GeneratorOperation::IsingXY, "GeneratorIsingXY"},
GeneratorView{GeneratorOperation::IsingYY, "GeneratorIsingYY"},
GeneratorView{GeneratorOperation::IsingZZ, "GeneratorIsingZZ"},
GeneratorView{GeneratorOperation::PhaseShift, "PhaseShift"},
GeneratorView{GeneratorOperation::RX, "RX"},
GeneratorView{GeneratorOperation::RY, "RY"},
GeneratorView{GeneratorOperation::RZ, "RZ"},
GeneratorView{GeneratorOperation::CRX, "CRX"},
GeneratorView{GeneratorOperation::CRY, "CRY"},
GeneratorView{GeneratorOperation::CRZ, "CRZ"},
GeneratorView{GeneratorOperation::IsingXX, "IsingXX"},
GeneratorView{GeneratorOperation::IsingXY, "IsingXY"},
GeneratorView{GeneratorOperation::IsingYY, "IsingYY"},
GeneratorView{GeneratorOperation::IsingZZ, "IsingZZ"},
GeneratorView{GeneratorOperation::ControlledPhaseShift,
"GeneratorControlledPhaseShift"},
GeneratorView{GeneratorOperation::SingleExcitation,
"GeneratorSingleExcitation"},
"ControlledPhaseShift"},
GeneratorView{GeneratorOperation::SingleExcitation, "SingleExcitation"},
GeneratorView{GeneratorOperation::SingleExcitationMinus,
"GeneratorSingleExcitationMinus"},
"SingleExcitationMinus"},
GeneratorView{GeneratorOperation::SingleExcitationPlus,
"GeneratorSingleExcitationPlus"},
GeneratorView{GeneratorOperation::MultiRZ, "GeneratorMultiRZ"},
GeneratorView{GeneratorOperation::DoubleExcitation,
"GeneratorDoubleExcitation"},
"SingleExcitationPlus"},
GeneratorView{GeneratorOperation::MultiRZ, "MultiRZ"},
GeneratorView{GeneratorOperation::DoubleExcitation, "DoubleExcitation"},
GeneratorView{GeneratorOperation::DoubleExcitationMinus,
"GeneratorDoubleExcitationMinus"},
"DoubleExcitationMinus"},
GeneratorView{GeneratorOperation::DoubleExcitationPlus,
"GeneratorDoubleExcitationPlus"},
GeneratorView{GeneratorOperation::GlobalPhase, "GeneratorGlobalPhase"},
"DoubleExcitationPlus"},
GeneratorView{GeneratorOperation::GlobalPhase, "GlobalPhase"},
};

using CGeneratorView =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
#include <Kokkos_Random.hpp>

#include "BitUtil.hpp" // isPerfectPowerOf2
#include "Constant.hpp"
#include "ConstantUtil.hpp"
#include "Error.hpp"
#include "GateFunctors.hpp"
#include "GateOperation.hpp"
Expand All @@ -39,12 +41,15 @@

/// @cond DEV
namespace {
using namespace Pennylane::Gates::Constant;
using namespace Pennylane::LightningKokkos::Functors;
using Pennylane::Gates::GateOperation;
using Pennylane::Gates::GeneratorOperation;
using Pennylane::Util::array_contains;
using Pennylane::Util::exp2;
using Pennylane::Util::isPerfectPowerOf2;
using Pennylane::Util::log2;
using namespace Pennylane::LightningKokkos::Functors;
using Pennylane::Util::reverse_lookup;
using std::size_t;
} // namespace
/// @endcond
Expand Down Expand Up @@ -110,9 +115,6 @@ class StateVectorKokkos final
data_ = std::make_unique<KokkosVector>("data_", exp2(num_qubits));
setBasisState(0U);
}

init_gates_indices_();
init_generators_indices_();
};

/**
Expand Down Expand Up @@ -265,7 +267,7 @@ class StateVectorKokkos final
} else {
applyControlledGlobalPhase<false>(gate_matrix);
}
} else if (gates_indices_.contains(opName)) {
} else if (array_contains(gate_names, std::string_view{opName})) {
applyNamedOperation(opName, wires, inverse, params);
} else {
PL_ABORT_IF(gate_matrix.size() == 0,
Expand Down Expand Up @@ -449,7 +451,7 @@ class StateVectorKokkos final
const std::vector<size_t> &wires,
bool inverse = false,
const std::vector<fp_t> &params = {}) {
switch (gates_indices_[opName]) {
switch (reverse_lookup(gate_names, std::string_view{opName})) {
case GateOperation::PauliX:
applyGateFunctor<pauliXFunctor, 1>(wires, inverse, params);
return;
Expand Down Expand Up @@ -576,10 +578,7 @@ class StateVectorKokkos final
auto applyGenerator(const std::string &opName,
const std::vector<size_t> &wires, bool inverse = false,
const std::vector<fp_t> &params = {}) -> fp_t {
if (!generators_indices_.contains(opName)) {
PL_ABORT(std::string("Generator does not exist for ") + opName);
}
switch (generators_indices_[opName]) {
switch (reverse_lookup(generator_names, std::string_view{opName})) {
case GeneratorOperation::RX:
applyGateFunctor<pauliXFunctor, 1>(wires, inverse, params);
return -static_cast<fp_t>(0.5);
Expand Down Expand Up @@ -855,81 +854,10 @@ class StateVectorKokkos final
}

private:
std::unordered_map<std::string, GateOperation> gates_indices_;
std::unordered_map<std::string, GeneratorOperation> generators_indices_;

size_t num_qubits_;
std::mutex init_mutex_;
std::unique_ptr<KokkosVector> data_;
inline static bool is_exit_reg_ = false;
// clang-format off
/**
* @brief Register gate operations in the gates_indices_ attribute:
* an unordered_map mapping strings to GateOperation enumeration keywords.
*/
void init_gates_indices_() {
gates_indices_["PauliX"] = GateOperation::PauliX;
gates_indices_["PauliY"] = GateOperation::PauliY;
gates_indices_["PauliZ"] = GateOperation::PauliZ;
gates_indices_["Hadamard"] = GateOperation::Hadamard;
gates_indices_["S"] = GateOperation::S;
gates_indices_["T"] = GateOperation::T;
gates_indices_["RX"] = GateOperation::RX;
gates_indices_["RY"] = GateOperation::RY;
gates_indices_["RZ"] = GateOperation::RZ;
gates_indices_["PhaseShift"] = GateOperation::PhaseShift;
gates_indices_["Rot"] = GateOperation::Rot;
gates_indices_["CY"] = GateOperation::CY;
gates_indices_["CZ"] = GateOperation::CZ;
gates_indices_["CNOT"] = GateOperation::CNOT;
gates_indices_["SWAP"] = GateOperation::SWAP;
gates_indices_["ControlledPhaseShift"] = GateOperation::ControlledPhaseShift;
gates_indices_["CRX"] = GateOperation::CRX;
gates_indices_["CRY"] = GateOperation::CRY;
gates_indices_["CRZ"] = GateOperation::CRZ;
gates_indices_["CRot"] = GateOperation::CRot;
gates_indices_["IsingXX"] = GateOperation::IsingXX;
gates_indices_["IsingXY"] = GateOperation::IsingXY;
gates_indices_["IsingYY"] = GateOperation::IsingYY;
gates_indices_["IsingZZ"] = GateOperation::IsingZZ;
gates_indices_["SingleExcitation"] = GateOperation::SingleExcitation;
gates_indices_["SingleExcitationMinus"] = GateOperation::SingleExcitationMinus;
gates_indices_["SingleExcitationPlus"] = GateOperation::SingleExcitationPlus;
gates_indices_["DoubleExcitation"] = GateOperation::DoubleExcitation;
gates_indices_["DoubleExcitationMinus"] = GateOperation::DoubleExcitationMinus;
gates_indices_["DoubleExcitationPlus"] = GateOperation::DoubleExcitationPlus;
gates_indices_["MultiRZ"] = GateOperation::MultiRZ;
gates_indices_["GlobalPhase"] = GateOperation::GlobalPhase;
gates_indices_["CSWAP"] = GateOperation::CSWAP;
gates_indices_["Toffoli"] = GateOperation::Toffoli;
}
/**
* @brief Register generator operations in the generators_indices_ attribute:
* an unordered_map mapping strings to GateOperation enumeration keywords.
*/
void init_generators_indices_() {
generators_indices_["RX"] = GeneratorOperation::RX;
generators_indices_["RY"] = GeneratorOperation::RY;
generators_indices_["RZ"] = GeneratorOperation::RZ;
generators_indices_["ControlledPhaseShift"] = GeneratorOperation::ControlledPhaseShift;
generators_indices_["CRX"] = GeneratorOperation::CRX;
generators_indices_["CRY"] = GeneratorOperation::CRY;
generators_indices_["CRZ"] = GeneratorOperation::CRZ;
generators_indices_["IsingXX"] = GeneratorOperation::IsingXX;
generators_indices_["IsingXY"] = GeneratorOperation::IsingXY;
generators_indices_["IsingYY"] = GeneratorOperation::IsingYY;
generators_indices_["IsingZZ"] = GeneratorOperation::IsingZZ;
generators_indices_["SingleExcitation"] = GeneratorOperation::SingleExcitation;
generators_indices_["SingleExcitationMinus"] = GeneratorOperation::SingleExcitationMinus;
generators_indices_["SingleExcitationPlus"] = GeneratorOperation::SingleExcitationPlus;
generators_indices_["DoubleExcitation"] = GeneratorOperation::DoubleExcitation;
generators_indices_["DoubleExcitationMinus"] = GeneratorOperation::DoubleExcitationMinus;
generators_indices_["DoubleExcitationPlus"] = GeneratorOperation::DoubleExcitationPlus;
generators_indices_["PhaseShift"] = GeneratorOperation::PhaseShift;
generators_indices_["MultiRZ"] = GeneratorOperation::MultiRZ;
generators_indices_["GlobalPhase"] = GeneratorOperation::GlobalPhase;
}
// clang-format on
};

}; // namespace Pennylane::LightningKokkos
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ TEMPLATE_TEST_CASE("StateVectorKokkos::applyGenerator - errors",
StateVectorKokkos<TestType> state_vector{num_qubits};
PL_REQUIRE_THROWS_MATCHES(state_vector.applyGenerator("XXX", {0}),
LightningException,
"Generator does not exist for");
"The given value does not exist.");
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ TEMPLATE_TEST_CASE("StateVectorKokkos::applyNamedOperation",
StateVectorKokkos<TestType> state_vector{num_qubits};
PL_REQUIRE_THROWS_MATCHES(state_vector.applyNamedOperation("XXX", {0}),
LightningException,
"Operation does not exist for");
"The given value does not exist.");
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ using Pennylane::Util::PairHash;

namespace Pennylane::LightningQubit::Internal {
constexpr auto generatorNamesWithoutPrefix() {
constexpr std::string_view prefix{"Generator"};
namespace GateConstant = Pennylane::Gates::Constant;
std::array<std::pair<GeneratorOperation, std::string_view>,
GateConstant::generator_names.size()>
Expand All @@ -60,7 +59,7 @@ constexpr auto generatorNamesWithoutPrefix() {
// NOLINTBEGIN(cppcoreguidelines-pro-bounds-constant-array-index)
const auto [gntr_op, gntr_name] = GateConstant::generator_names[i];
res[i].first = gntr_op;
res[i].second = gntr_name.substr(prefix.size());
res[i].second = gntr_name.substr(0);
// NOLINTEND(cppcoreguidelines-pro-bounds-constant-array-index)
}
return res;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,6 @@ static_assert(
Util::count_unique(Util::second_elems_of(Constant::generator_names)) ==
Constant::generator_names.size(),
"Second elements of generator_names must be distinct.");
static_assert(check_generator_names_starts_with(),
"Names of generators must start with \"Generator\"");

/*******************************************************************************
* Check gate_wires is well defined
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,18 +46,9 @@ using namespace Pennylane::Util;
} // namespace
/// @endcond

/**
* @brief As clang does not support constexpr string_view::remove_prefix yet.
*/
constexpr std::string_view remove_prefix(const std::string_view &str,
size_t len) {
return {str.data() + len, str.length() - len};
}

template <GeneratorOperation gntr_op>
constexpr auto findGateOpForGenerator() -> GateOperation {
constexpr auto gntr_name =
remove_prefix(lookup(Constant::generator_names, gntr_op), 9);
constexpr auto gntr_name = lookup(Constant::generator_names, gntr_op);

for (const auto &[gate_op, gate_name] : Constant::gate_names) {
if (gate_name == gntr_name) {
Expand Down
47 changes: 46 additions & 1 deletion pennylane_lightning/core/src/utils/ConstantUtil.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,13 @@
#include <cstdlib>
#include <stdexcept>
#include <tuple>
#include <unordered_map>

#if __has_include(<version>)
#include <version>
#endif

#include "Error.hpp"
#include "TypeTraits.hpp"
#include "Util.hpp"

Expand All @@ -49,7 +51,29 @@ constexpr auto lookup(const std::array<std::pair<Key, Value>, size> &arr,
return std::get<1>(arr[idx]);
}
}
throw std::range_error("The given key does not exist.");
PL_ABORT("The given key does not exist.");
}

/**
* @brief Reverse lookup value in array of pairs. For a constexpr map-like
* behavior.
*
* @tparam Key Type of keys
* @tparam Value Type of values
* @tparam size Size of std::array
* @param arr Array to lookup
* @param value Value to find
*/
template <typename Key, typename Value, size_t size>
constexpr auto
reverse_lookup(const std::array<std::pair<Key, Value>, size> &arr,
const Value &value) -> Key {
for (size_t idx = 0; idx < size; idx++) {
if (std::get<1>(arr[idx]) == value) {
return std::get<0>(arr[idx]);
}
}
PL_ABORT("The given value does not exist.");
}

/**
Expand All @@ -71,6 +95,27 @@ constexpr auto array_has_elem(const std::array<U, size> &arr, const U &elem)
return false;
}

/**
* @brief Check an array of pairs contains a certain value.
*
* @tparam Key Type of keys
* @tparam Value Type of values
* @tparam size Size of std::array
* @param arr Array to lookup
* @param value Value to find
*/
template <typename Key, typename Value, size_t size>
constexpr auto
array_contains(const std::array<std::pair<Key, Value>, size> &arr,
const Value &value) -> bool {
for (size_t idx = 0; idx < size; idx++) {
if (std::get<1>(arr[idx]) == value) {
return true;
}
}
return false;
}

/// @cond DEV
namespace Internal {
/**
Expand Down
14 changes: 7 additions & 7 deletions pennylane_lightning/lightning_gpu/lightning_gpu.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,13 @@
from pennylane.ops.op_math import Adjoint
from pennylane.wires import Wires

# pylint: disable=import-error, no-name-in-module, ungrouped-imports
from pennylane_lightning.core._serialize import (
QuantumScriptSerializer,
global_phase_diagonal,
)
from pennylane_lightning.core._version import __version__

# pylint: disable=no-name-in-module, ungrouped-imports
from pennylane_lightning.lightning_gpu_ops.algorithms import (
AdjointJacobianC64,
Expand All @@ -99,13 +106,6 @@
create_ops_listC128,
)

# pylint: disable=import-error, no-name-in-module, ungrouped-imports
from pennylane_lightning.core._serialize import (
QuantumScriptSerializer,
global_phase_diagonal,
)
from pennylane_lightning.core._version import __version__

if MPI_SUPPORT:
from pennylane_lightning.lightning_gpu_ops.algorithmsMPI import (
AdjointJacobianMPIC64,
Expand Down
Loading

0 comments on commit 6c758e4

Please sign in to comment.