Program Listing for File ObservablesKokkos.hpp¶
↰ Return to documentation for file (pennylane_lightning/core/src/simulators/lightning_kokkos/observables/ObservablesKokkos.hpp
)
// Copyright 2018-2023 Xanadu Quantum Technologies Inc.
// Licensed under the Apache License, Version 2.0 (the License);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an AS IS BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <vector>
#include <Kokkos_Core.hpp>
#include "Constant.hpp"
#include "ConstantUtil.hpp" // lookup
#include "Error.hpp"
#include "LinearAlgebraKokkos.hpp"
#include "Observables.hpp"
#include "StateVectorKokkos.hpp"
#include "Util.hpp"
// using namespace Pennylane;
namespace {
using namespace Pennylane::Util;
using namespace Pennylane::Observables;
using Pennylane::LightningKokkos::StateVectorKokkos;
using Pennylane::LightningKokkos::Util::SparseMV_Kokkos;
} // namespace
namespace Pennylane::LightningKokkos::Observables {
template <class StateVectorT>
class NamedObs final : public NamedObsBase<StateVectorT> {
private:
using BaseType = NamedObsBase<StateVectorT>;
public:
using PrecisionT = typename StateVectorT::PrecisionT;
NamedObs(std::string obs_name, std::vector<std::size_t> wires,
std::vector<PrecisionT> params = {})
: BaseType{obs_name, wires, params} {
using Pennylane::Gates::Constant::gate_names;
using Pennylane::Gates::Constant::gate_num_params;
using Pennylane::Gates::Constant::gate_wires;
const auto gate_op = lookup(reverse_pairs(gate_names),
std::string_view{this->obs_name_});
PL_ASSERT(lookup(gate_wires, gate_op) == this->wires_.size());
PL_ASSERT(lookup(gate_num_params, gate_op) == this->params_.size());
}
};
template <class StateVectorT>
class HermitianObs final : public HermitianObsBase<StateVectorT> {
private:
using BaseType = HermitianObsBase<StateVectorT>;
public:
using PrecisionT = typename StateVectorT::PrecisionT;
using ComplexT = typename StateVectorT::ComplexT;
using MatrixT = std::vector<ComplexT>;
HermitianObs(MatrixT matrix, std::vector<std::size_t> wires)
: BaseType{matrix, wires} {}
};
template <class StateVectorT>
class TensorProdObs final : public TensorProdObsBase<StateVectorT> {
private:
using BaseType = TensorProdObsBase<StateVectorT>;
public:
using PrecisionT = typename StateVectorT::PrecisionT;
template <typename... Ts>
explicit TensorProdObs(Ts &&...arg) : BaseType{arg...} {}
static auto
create(std::initializer_list<std::shared_ptr<Observable<StateVectorT>>> obs)
-> std::shared_ptr<TensorProdObs<StateVectorT>> {
return std::shared_ptr<TensorProdObs<StateVectorT>>{
new TensorProdObs(std::move(obs))};
}
static auto
create(std::vector<std::shared_ptr<Observable<StateVectorT>>> obs)
-> std::shared_ptr<TensorProdObs<StateVectorT>> {
return std::shared_ptr<TensorProdObs<StateVectorT>>{
new TensorProdObs(std::move(obs))};
}
};
template <class StateVectorT>
class Hamiltonian final : public HamiltonianBase<StateVectorT> {
private:
using BaseType = HamiltonianBase<StateVectorT>;
public:
using PrecisionT = typename StateVectorT::PrecisionT;
using ComplexT = typename StateVectorT::ComplexT;
template <typename T1, typename T2>
explicit Hamiltonian(T1 &&coeffs, T2 &&obs) : BaseType{coeffs, obs} {}
static auto
create(std::initializer_list<PrecisionT> coeffs,
std::initializer_list<std::shared_ptr<Observable<StateVectorT>>> obs)
-> std::shared_ptr<Hamiltonian<StateVectorT>> {
return std::shared_ptr<Hamiltonian<StateVectorT>>(
new Hamiltonian<StateVectorT>{std::move(coeffs), std::move(obs)});
}
void applyInPlace(StateVectorT &sv) const override {
StateVectorT buffer{sv.getNumQubits()};
buffer.initZeros();
for (size_t term_idx = 0; term_idx < this->coeffs_.size(); term_idx++) {
StateVectorT tmp{sv};
this->obs_[term_idx]->applyInPlace(tmp);
LightningKokkos::Util::axpy_Kokkos<PrecisionT>(
ComplexT{this->coeffs_[term_idx], 0.0}, tmp.getView(),
buffer.getView(), tmp.getLength());
}
sv.updateData(buffer);
}
};
template <class StateVectorT>
class SparseHamiltonian final : public SparseHamiltonianBase<StateVectorT> {
private:
using BaseType = SparseHamiltonianBase<StateVectorT>;
public:
using PrecisionT = typename StateVectorT::PrecisionT;
using ComplexT = typename StateVectorT::ComplexT;
using IdxT = typename BaseType::IdxT;
template <typename T1, typename T2, typename T3 = T2, typename T4>
explicit SparseHamiltonian(T1 &&data, T2 &&indices, T3 &&offsets,
T4 &&wires)
: BaseType{data, indices, offsets, wires} {}
static auto create(std::initializer_list<ComplexT> data,
std::initializer_list<IdxT> indices,
std::initializer_list<IdxT> offsets,
std::initializer_list<std::size_t> wires)
-> std::shared_ptr<SparseHamiltonian<StateVectorT>> {
return std::shared_ptr<SparseHamiltonian<StateVectorT>>(
new SparseHamiltonian<StateVectorT>{
std::move(data), std::move(indices), std::move(offsets),
std::move(wires)});
}
void applyInPlace(StateVectorT &sv) const override {
PL_ABORT_IF_NOT(this->wires_.size() == sv.getNumQubits(),
"SparseH wire count does not match state-vector size");
StateVectorT d_sv_prime(sv.getNumQubits());
SparseMV_Kokkos<PrecisionT, ComplexT>(
sv.getView(), d_sv_prime.getView(), this->offsets_.data(),
this->offsets_.size(), this->indices_.data(), this->data_.data(),
this->data_.size());
sv.updateData(d_sv_prime);
}
};
namespace detail {
using Pennylane::LightningKokkos::Util::axpy_Kokkos;
// Default implementation
template <class StateVectorT, bool use_openmp> struct HamiltonianApplyInPlace {
using PrecisionT = typename StateVectorT::PrecisionT;
using ComplexT = typename StateVectorT::ComplexT;
using KokkosVector = typename StateVectorT::KokkosVector;
static void
run(const std::vector<PrecisionT> &coeffs,
const std::vector<std::shared_ptr<Observable<StateVectorT>>> &terms,
StateVectorT &sv) {
KokkosVector res("results", sv.getLength());
Kokkos::deep_copy(res, ComplexT{0.0, 0.0});
for (size_t term_idx = 0; term_idx < coeffs.size(); term_idx++) {
StateVectorT tmp{sv};
terms[term_idx]->applyInPlace(tmp);
LightningKokkos::Util::axpy_Kokkos<PrecisionT>(
ComplexT{coeffs[term_idx], 0.0}, tmp.getView(), res,
tmp.getLength());
}
sv.updateData(res);
}
};
} // namespace detail
} // namespace Pennylane::LightningKokkos::Observables
api/program_listing_file_pennylane_lightning_core_src_simulators_lightning_kokkos_observables_ObservablesKokkos.hpp
Download Python script
Download Notebook
View on GitHub