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 Hamiltonian expval in the forward path #333

Merged
merged 15 commits into from
Aug 23, 2022
Merged
3 changes: 3 additions & 0 deletions .github/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
* Introduces requirements-dev.txt and improves dockerfile.
[(#330)](https://github.com/PennyLaneAI/pennylane-lightning/pull/330)

* Support `expval` for a Hamiltonian.
[(#333)](https://github.com/PennyLaneAI/pennylane-lightning/pull/333)

### Documentation

### Bug fixes
Expand Down
3 changes: 2 additions & 1 deletion pennylane_lightning/_serialize.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
from pennylane.grouping import is_pauli_word
from pennylane.operation import Observable, Tensor
from pennylane.tape import QuantumTape
from pennylane.math import unwrap

# Remove after the next release of PL
# Add from pennylane import matrix
Expand Down Expand Up @@ -111,7 +112,7 @@ def _serialize_hamiltonian(ob, wires_map: dict, use_csingle: bool):
rtype = np.float64
hamiltonian_obs = HamiltonianC128

coeffs = np.array(ob.coeffs).astype(rtype)
coeffs = np.array(unwrap(ob.coeffs)).astype(rtype)
mlxd marked this conversation as resolved.
Show resolved Hide resolved
mlxd marked this conversation as resolved.
Show resolved Hide resolved
terms = [_serialize_ob(t, wires_map, use_csingle) for t in ob.ops]
return hamiltonian_obs(coeffs, terms)

Expand Down
2 changes: 1 addition & 1 deletion pennylane_lightning/_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.26.0-dev3"
__version__ = "0.26.0-dev4"
8 changes: 5 additions & 3 deletions pennylane_lightning/lightning_qubit.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
best_alignment,
)

from ._serialize import _serialize_observables, _serialize_ops
from ._serialize import _serialize_ob, _serialize_observables, _serialize_ops

CPP_BINARY_AVAILABLE = True
except ModuleNotFoundError:
Expand Down Expand Up @@ -621,8 +621,6 @@ def expval(self, observable, shot_range=None, bin_size=None):
if isinstance(observable.name, List) or observable.name in [
"Identity",
"Projector",
"Hermitian",
"Hamiltonian",
]:
return super().expval(observable, shot_range=shot_range, bin_size=bin_size)

Expand All @@ -648,6 +646,10 @@ def expval(self, observable, shot_range=None, bin_size=None):
)
return super().expval(observable, shot_range=shot_range, bin_size=bin_size)

if observable.name in ["Hamiltonian", "Hermitian"]:
ob_serialized = _serialize_ob(observable, self.wire_map, use_csingle=self.use_csingle)
return M.expval(ob_serialized)

# translate to wire labels used by device
observable_wires = self.map_wires(observable.wires)

Expand Down
11 changes: 6 additions & 5 deletions pennylane_lightning/src/algorithms/AlgUtil.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ inline void applyOperationAdj(StateVectorManagedCPU<T> &state,
*/
template <typename T>
inline void applyObservable(StateVectorManagedCPU<T> &state,
Observable<T> &observable) {
Simulators::Observable<T> &observable) {
observable.applyInPlace(state);
}

Expand All @@ -79,10 +79,11 @@ inline void applyObservable(StateVectorManagedCPU<T> &state,
* @param observables Vector of observables to apply to each statevector.
*/
template <typename T>
inline void applyObservables(
std::vector<StateVectorManagedCPU<T>> &states,
const StateVectorManagedCPU<T> &reference_state,
const std::vector<std::shared_ptr<Observable<T>>> &observables) {
inline void
applyObservables(std::vector<StateVectorManagedCPU<T>> &states,
const StateVectorManagedCPU<T> &reference_state,
const std::vector<std::shared_ptr<Simulators::Observable<T>>>
&observables) {
std::exception_ptr ex = nullptr;
size_t num_observables = observables.size();

Expand Down
2 changes: 1 addition & 1 deletion pennylane_lightning/src/algorithms/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
project(lightning_algorithms LANGUAGES CXX)

set(ALGORITHM_FILES AdjointDiff.cpp Observables.cpp JacobianTape.cpp StateVecAdjDiff.cpp CACHE INTERNAL "" FORCE)
set(ALGORITHM_FILES AdjointDiff.cpp JacobianTape.cpp StateVecAdjDiff.cpp CACHE INTERNAL "" FORCE)
add_library(lightning_algorithms STATIC ${ALGORITHM_FILES})

target_link_libraries(lightning_algorithms PRIVATE lightning_compile_options
Expand Down
6 changes: 3 additions & 3 deletions pennylane_lightning/src/algorithms/JacobianTape.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ template <class T> class JacobianData {
* @var observables
* Observables for which to calculate Jacobian.
*/
const std::vector<std::shared_ptr<Observable<T>>> observables;
const std::vector<std::shared_ptr<Simulators::Observable<T>>> observables;

/**
* @var operations
Expand Down Expand Up @@ -238,7 +238,7 @@ template <class T> class JacobianData {
* @endrst
*/
JacobianData(size_t num_params, size_t num_elem, std::complex<T> *ps,
std::vector<std::shared_ptr<Observable<T>>> obs,
std::vector<std::shared_ptr<Simulators::Observable<T>>> obs,
OpsData<T> ops, std::vector<size_t> trainP)
: num_parameters(num_params), num_elements(num_elem), psi(ps),
observables(std::move(obs)), operations(std::move(ops)),
Expand Down Expand Up @@ -278,7 +278,7 @@ template <class T> class JacobianData {
* @return List of observables
*/
[[nodiscard]] auto getObservables() const
-> const std::vector<std::shared_ptr<Observable<T>>> & {
-> const std::vector<std::shared_ptr<Simulators::Observable<T>>> & {
return observables;
}

Expand Down
11 changes: 10 additions & 1 deletion pennylane_lightning/src/bindings/Bindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "Bindings.hpp"

#include "GateUtil.hpp"
#include "Measures.hpp"
#include "StateVecAdjDiff.hpp"
#include "StateVectorManagedCPU.hpp"

Expand All @@ -27,6 +28,7 @@
namespace {
using namespace Pennylane;
using namespace Pennylane::Util;
using namespace Pennylane::Simulators;
using namespace Pennylane::Algorithms;
using namespace Pennylane::Gates;

Expand Down Expand Up @@ -95,6 +97,13 @@ void lightning_class_bindings(py::module_ &m) {
const std::string &, const std::vector<size_t> &)>(
&Measures<PrecisionT>::expval),
"Expected value of an operation by name.")
.def(
"expval",
[](Measures<PrecisionT> &M,
const std::shared_ptr<Observable<PrecisionT>> &ob) {
return M.expval(*ob);
},
"Expected value of an operation object.")
.def(
"expval",
[](Measures<PrecisionT> &M, const np_arr_sparse_ind row_map,
Expand Down Expand Up @@ -413,7 +422,7 @@ PYBIND11_MODULE(lightning_qubit_ops, // NOLINT: No control over Pybind internals
/* Add compile info */
m.def("compile_info", &getCompileInfo, "Compiled binary information.");

/* Add compile info */
/* Add runtime info */
m.def("runtime_info", &getRuntimeInfo, "Runtime information.");

/* Add Kokkos and Kokkos Kernels info */
Expand Down
16 changes: 3 additions & 13 deletions pennylane_lightning/src/simulator/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,23 +1,13 @@
project(lightning_simulator)

set(SIMULATOR_FILES StateVectorRawCPU.cpp StateVectorManagedCPU.cpp Measures.cpp CACHE INTERNAL "" FORCE)
set(SIMULATOR_FILES StateVectorRawCPU.cpp Observables.cpp StateVectorManagedCPU.cpp Measures.cpp CACHE INTERNAL "" FORCE)

add_library(lightning_simulator STATIC ${SIMULATOR_FILES})

if (UNIX AND (${CMAKE_SYSTEM_PROCESSOR} MATCHES "(AMD64)|(X64)|(x64)|(x86_64)"))
add_library(lightning_simulator_assign_kernels_x64 STATIC KernelMap_X64.cpp AssignKernelMap_AVX2.cpp AssignKernelMap_AVX512.cpp AssignKernelMap_Default.cpp)
target_link_libraries(lightning_simulator_assign_kernels_x64 PRIVATE lightning_compile_options
lightning_external_libs
lightning_gates
lightning_utils)
target_link_libraries(lightning_simulator PRIVATE lightning_simulator_assign_kernels_x64)
target_sources(lightning_simulator PRIVATE KernelMap_X64.cpp AssignKernelMap_AVX2.cpp AssignKernelMap_AVX512.cpp AssignKernelMap_Default.cpp)
else()
add_library(lightning_simulator_assign_kernels_default STATIC KernelMap_Default.cpp AssignKernelMap_Default.cpp)
target_link_libraries(lightning_simulator_assign_kernels_default PRIVATE lightning_compile_options
lightning_external_libs
lightning_gates
lightning_utils)
target_link_libraries(lightning_simulator PRIVATE lightning_simulator_assign_kernels_default)
target_sources(lightning_simulator PRIVATE KernelMap_Default.cpp AssignKernelMap_Default.cpp)
endif()

target_include_directories(lightning_simulator PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
Expand Down
7 changes: 4 additions & 3 deletions pennylane_lightning/src/simulator/Measures.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "Measures.hpp"

// explicit instantiation
template class Pennylane::Measures<float, Pennylane::StateVectorRawCPU<float>>;
template class Pennylane::Measures<double,
Pennylane::StateVectorRawCPU<double>>;
template class Pennylane::Simulators::Measures<
float, Pennylane::StateVectorRawCPU<float>>;
template class Pennylane::Simulators::Measures<
double, Pennylane::StateVectorRawCPU<double>>;
19 changes: 17 additions & 2 deletions pennylane_lightning/src/simulator/Measures.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,11 @@

#include "Kokkos_Sparse.hpp"
#include "LinearAlgebra.hpp"
#include "Observables.hpp"
#include "StateVectorManagedCPU.hpp"
#include "StateVectorRawCPU.hpp"

namespace Pennylane {
namespace Pennylane::Simulators {
chaeyeunpark marked this conversation as resolved.
Show resolved Hide resolved

/**
* @brief Observable's Measurement Class.
Expand Down Expand Up @@ -217,6 +218,20 @@ class Measures {
return expected_value_list;
}

/**
* @brief Expectation value for a general Observable
*
* @param ob Observable
*/
auto expval(const Observable<fp_t> &ob) -> fp_t {
StateVectorManagedCPU<fp_t> op_sv(original_statevector);
ob.applyInPlace(op_sv);
const auto inner_prod =
Util::innerProdC(original_statevector.getData(), op_sv.getData(),
original_statevector.getLength());
return std::real(inner_prod);
}

/**
* @brief Variance of an observable.
*
Expand Down Expand Up @@ -380,4 +395,4 @@ class Measures {
return samples;
}
}; // class Measures
} // namespace Pennylane
} // namespace Pennylane::Simulators
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@

#include "Observables.hpp"

template class Pennylane::Algorithms::NamedObs<float>;
template class Pennylane::Algorithms::NamedObs<double>;
template class Pennylane::Simulators::NamedObs<float>;
template class Pennylane::Simulators::NamedObs<double>;

template class Pennylane::Algorithms::HermitianObs<float>;
template class Pennylane::Algorithms::HermitianObs<double>;
template class Pennylane::Simulators::HermitianObs<float>;
template class Pennylane::Simulators::HermitianObs<double>;

template class Pennylane::Algorithms::TensorProdObs<float>;
template class Pennylane::Algorithms::TensorProdObs<double>;
template class Pennylane::Simulators::TensorProdObs<float>;
template class Pennylane::Simulators::TensorProdObs<double>;

template class Pennylane::Algorithms::Hamiltonian<float>;
template class Pennylane::Algorithms::Hamiltonian<double>;
template class Pennylane::Simulators::Hamiltonian<float>;
template class Pennylane::Simulators::Hamiltonian<double>;
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
#include <memory>
#include <unordered_set>

namespace Pennylane::Algorithms {
namespace Pennylane::Simulators {

/**
* @brief A base class for all observable classes.
Expand Down Expand Up @@ -442,4 +442,4 @@ template <typename T> class Hamiltonian final : public Observable<T> {
}
};

} // namespace Pennylane::Algorithms
} // namespace Pennylane::Simulators
3 changes: 2 additions & 1 deletion pennylane_lightning/src/tests/Test_AdjDiff.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

using namespace Pennylane;
using namespace Pennylane::Algorithms;
using namespace Pennylane::Simulators;

TEST_CASE("Algorithms::adjointJacobian Op=RX, Obs=Z", "[Algorithms]") {
const std::vector<double> param{-M_PI / 7, M_PI / 5, 2 * M_PI / 3};
Expand Down Expand Up @@ -540,7 +541,7 @@ TEST_CASE(
"Algorithms::adjointJacobian with exceedingly complicated Hamiltonian",
"[Algorithms]") {
using namespace std::literals;
using Pennylane::Algorithms::detail::HamiltonianApplyInPlace;
using Pennylane::Simulators::detail::HamiltonianApplyInPlace;

std::vector<double> param{-M_PI / 7, M_PI / 5, 2 * M_PI / 3};
std::vector<size_t> t_params{0, 2};
Expand Down
1 change: 1 addition & 0 deletions pennylane_lightning/src/tests/Test_AlgUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

using namespace Pennylane;
using namespace Pennylane::Algorithms;
using namespace Pennylane::Simulators;

class TestException : public std::exception {};

Expand Down
1 change: 1 addition & 0 deletions pennylane_lightning/src/tests/Test_Measures.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

using namespace Pennylane;
using namespace Pennylane::Util;
using namespace Pennylane::Simulators;

using std::complex;
using std::size_t;
Expand Down
1 change: 1 addition & 0 deletions pennylane_lightning/src/tests/Test_Measures_Sparse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

using namespace Pennylane;
using namespace Pennylane::Util;
using namespace Pennylane::Simulators;

namespace {
using std::complex;
Expand Down
2 changes: 1 addition & 1 deletion pennylane_lightning/src/tests/Test_Observables.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#include <catch2/catch.hpp>

using namespace Pennylane;
using namespace Pennylane::Algorithms;
using namespace Pennylane::Simulators;
using Pennylane::Util::LightningException;

// NOLINTNEXTLINE(readability-function-cognitive-complexity)
Expand Down
1 change: 1 addition & 0 deletions pennylane_lightning/src/tests/Test_StateVecAdjDiff.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
using namespace Pennylane;
using namespace Pennylane::Util;
using namespace Pennylane::Algorithms;
using namespace Pennylane::Simulators;

/**
* @brief
Expand Down
Loading