Program Listing for File UtilKokkos.hpp¶
↰ Return to documentation for file (pennylane_lightning/core/simulators/lightning_kokkos/utils/UtilKokkos.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 "BitUtil.hpp"
#include "Util.hpp"
#include <Kokkos_Core.hpp>
namespace {
using namespace Pennylane::Util;
using KokkosIntVector = Kokkos::View<std::size_t *>;
} // namespace
namespace Pennylane::LightningKokkos::Util {
constexpr std::size_t one{1};
template <typename T>
inline auto view2vector(const Kokkos::View<T *> view) -> std::vector<T> {
using UnmanagedHostView =
Kokkos::View<T *, Kokkos::HostSpace,
Kokkos::MemoryTraits<Kokkos::Unmanaged>>;
std::vector<T> vec(view.size());
Kokkos::deep_copy(UnmanagedHostView(vec.data(), vec.size()), view);
return vec;
}
template <typename T>
inline auto pointer2view(const T *vec, const std::size_t num)
-> Kokkos::View<T *> {
using UnmanagedView = Kokkos::View<const T *, Kokkos::HostSpace,
Kokkos::MemoryTraits<Kokkos::Unmanaged>>;
Kokkos::View<T *> view("vec", num);
Kokkos::deep_copy(view, UnmanagedView(vec, num));
return view;
}
template <typename T>
inline auto vector2view(const std::vector<T> &vec) -> Kokkos::View<T *> {
return pointer2view(vec.data(), vec.size());
}
inline auto wires2Parity(const std::size_t num_qubits,
const std::vector<std::size_t> &wires)
-> std::pair<KokkosIntVector, KokkosIntVector> {
KokkosIntVector parity;
KokkosIntVector rev_wire_shifts;
std::vector<std::size_t> rev_wires_(wires.size());
std::vector<std::size_t> rev_wire_shifts_(wires.size());
for (std::size_t k = 0; k < wires.size(); k++) {
rev_wires_[k] = (num_qubits - 1) - wires[(wires.size() - 1) - k];
rev_wire_shifts_[k] = (one << rev_wires_[k]);
}
const std::vector<std::size_t> parity_ = revWireParity(rev_wires_);
Kokkos::View<const std::size_t *, Kokkos::HostSpace,
Kokkos::MemoryTraits<Kokkos::Unmanaged>>
rev_wire_shifts_host(rev_wire_shifts_.data(), rev_wire_shifts_.size());
Kokkos::resize(rev_wire_shifts, rev_wire_shifts_host.size());
Kokkos::deep_copy(rev_wire_shifts, rev_wire_shifts_host);
Kokkos::View<const std::size_t *, Kokkos::HostSpace,
Kokkos::MemoryTraits<Kokkos::Unmanaged>>
parity_host(parity_.data(), parity_.size());
Kokkos::resize(parity, parity_host.size());
Kokkos::deep_copy(parity, parity_host);
return {parity, rev_wire_shifts};
}
inline auto reverseWires(const std::size_t num_qubits,
const std::vector<std::size_t> &wires,
const std::vector<std::size_t> &controlled_wires)
-> std::pair<KokkosIntVector, KokkosIntVector> {
KokkosIntVector parity;
KokkosIntVector rev_wires;
const std::size_t n_contr = controlled_wires.size();
const std::size_t n_wires = wires.size();
const std::size_t nw_tot = n_contr + n_wires;
std::vector<std::size_t> all_wires;
all_wires.reserve(nw_tot);
all_wires.insert(all_wires.begin(), wires.begin(), wires.end());
all_wires.insert(all_wires.begin() + n_wires, controlled_wires.begin(),
controlled_wires.end());
std::vector<std::size_t> rev_wires_(nw_tot, (num_qubits - 1));
std::transform(rev_wires_.begin(), rev_wires_.end(), all_wires.rbegin(),
rev_wires_.begin(), std::minus<>{});
const std::vector<std::size_t> parity_ = revWireParity(rev_wires_);
Kokkos::View<const std::size_t *, Kokkos::HostSpace,
Kokkos::MemoryTraits<Kokkos::Unmanaged>>
rev_wires_host(rev_wires_.data(), rev_wires_.size());
Kokkos::resize(rev_wires, rev_wires_host.size());
Kokkos::deep_copy(rev_wires, rev_wires_host);
Kokkos::View<const std::size_t *, Kokkos::HostSpace,
Kokkos::MemoryTraits<Kokkos::Unmanaged>>
parity_host(parity_.data(), parity_.size());
Kokkos::resize(parity, parity_host.size());
Kokkos::deep_copy(parity, parity_host);
return {parity, rev_wires};
}
inline auto generateBitPatterns(const std::vector<std::size_t> &wires,
const std::size_t num_qubits)
-> std::vector<std::size_t> {
std::vector<std::size_t> indices;
indices.reserve(Pennylane::Util::exp2(wires.size()));
indices.emplace_back(0);
for (auto index_it = wires.rbegin(); index_it != wires.rend(); index_it++) {
const std::size_t value =
Pennylane::Util::maxDecimalForQubit(*index_it, num_qubits);
const std::size_t currentSize = indices.size();
for (std::size_t j = 0; j < currentSize; j++) {
indices.emplace_back(indices[j] + value);
}
}
return indices;
}
inline void controlBitPatterns(std::vector<std::size_t> &indices,
const std::size_t num_qubits,
const std::vector<std::size_t> &controlled_wires,
const std::vector<bool> &controlled_values) {
if (controlled_wires.empty()) {
return;
}
std::vector<std::size_t> masks(controlled_wires.size());
std::vector<std::size_t> values(controlled_wires.size());
for (std::size_t k = 0; k < controlled_wires.size(); k++) {
const std::size_t rev_wire = num_qubits - 1 - controlled_wires[k];
masks[k] = ~(one << rev_wire);
values[k] = static_cast<std::size_t>(controlled_values[k]) << rev_wire;
}
std::for_each(indices.begin(), indices.end(),
[&masks, &values](std::size_t &i) {
for (std::size_t k = 0; k < masks.size(); k++) {
i = (i & masks[k]) | values[k];
}
});
}
KOKKOS_INLINE_FUNCTION std::size_t
parity_2_offset(const KokkosIntVector &parity, const std::size_t k) {
std::size_t offset{0U};
for (std::size_t i = 0; i < parity.size(); i++) {
offset |= ((k << i) & parity(i));
}
return offset;
}
} // namespace Pennylane::LightningKokkos::Util
api/program_listing_file_pennylane_lightning_core_simulators_lightning_kokkos_utils_UtilKokkos.hpp
Download Python script
Download Notebook
View on GitHub