Program Listing for File cuGates_host.hpp¶
↰ Return to documentation for file (pennylane_lightning/core/src/utils/cuda_utils/cuGates_host.hpp
)
// Copyright 2022-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 <cmath>
#include <complex>
#include <functional>
#include <vector>
#include "cuda_helpers.hpp"
namespace {
namespace cuUtil = Pennylane::LightningGPU::Util;
using namespace cuUtil;
} // namespace
namespace Pennylane::LightningGPU::cuGates {
template <class CFP_t>
static constexpr auto getIdentity() -> std::vector<CFP_t> {
return {cuUtil::ONE<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ONE<CFP_t>()};
}
template <class CFP_t> static constexpr auto getPauliX() -> std::vector<CFP_t> {
return {cuUtil::ZERO<CFP_t>(), cuUtil::ONE<CFP_t>(), cuUtil::ONE<CFP_t>(),
cuUtil::ZERO<CFP_t>()};
}
template <class CFP_t> static constexpr auto getPauliY() -> std::vector<CFP_t> {
return {cuUtil::ZERO<CFP_t>(), -cuUtil::IMAG<CFP_t>(),
cuUtil::IMAG<CFP_t>(), cuUtil::ZERO<CFP_t>()};
}
template <class CFP_t> static constexpr auto getPauliZ() -> std::vector<CFP_t> {
return {cuUtil::ONE<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
-cuUtil::ONE<CFP_t>()};
}
template <class CFP_t>
static constexpr auto getHadamard() -> std::vector<CFP_t> {
return {cuUtil::INVSQRT2<CFP_t>(), cuUtil::INVSQRT2<CFP_t>(),
cuUtil::INVSQRT2<CFP_t>(), -cuUtil::INVSQRT2<CFP_t>()};
}
template <class CFP_t> static constexpr auto getS() -> std::vector<CFP_t> {
return {cuUtil::ONE<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::IMAG<CFP_t>()};
}
template <class CFP_t> static constexpr auto getT() -> std::vector<CFP_t> {
return {cuUtil::ONE<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ConstMultSC(
cuUtil::SQRT2<decltype(cuUtil::ONE<CFP_t>().x)>() / 2,
cuUtil::ConstSum(cuUtil::ONE<CFP_t>(), cuUtil::IMAG<CFP_t>()))};
}
template <class CFP_t> static constexpr auto getCNOT() -> std::vector<CFP_t> {
return {cuUtil::ONE<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ONE<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ONE<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ONE<CFP_t>(),
cuUtil::ZERO<CFP_t>()};
}
template <class CFP_t> static constexpr auto getSWAP() -> std::vector<CFP_t> {
return {cuUtil::ONE<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ONE<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ONE<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ONE<CFP_t>()};
}
template <class CFP_t> static constexpr auto getCY() -> std::vector<CFP_t> {
return {
cuUtil::ONE<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ONE<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(), -cuUtil::IMAG<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::IMAG<CFP_t>(),
cuUtil::ZERO<CFP_t>()};
}
template <class CFP_t> static constexpr auto getCZ() -> std::vector<CFP_t> {
return {cuUtil::ONE<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ONE<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ONE<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
-cuUtil::ONE<CFP_t>()};
}
template <class CFP_t> static constexpr auto getCSWAP() -> std::vector<CFP_t> {
return {cuUtil::ONE<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ONE<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ONE<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ONE<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ONE<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ONE<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ONE<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ONE<CFP_t>()};
}
template <class CFP_t>
static constexpr auto getToffoli() -> std::vector<CFP_t> {
return {cuUtil::ONE<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ONE<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ONE<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ONE<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ONE<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ONE<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ONE<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ONE<CFP_t>(),
cuUtil::ZERO<CFP_t>()};
}
template <class CFP_t, class U = double>
static auto getPhaseShift(U angle) -> std::vector<CFP_t> {
return {cuUtil::ONE<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
{std::cos(angle), std::sin(angle)}};
}
template <class CFP_t, class U = double>
static auto getPhaseShift(const std::vector<U> ¶ms) -> std::vector<CFP_t> {
return getPhaseShift<CFP_t>(params.front());
}
template <class CFP_t, class U = double>
static auto getRX(U angle) -> std::vector<CFP_t> {
const CFP_t c{std::cos(angle / 2), 0};
const CFP_t js{0, -std::sin(angle / 2)};
return {c, js, js, c};
}
template <class CFP_t, class U = double>
static auto getRX(const std::vector<U> ¶ms) -> std::vector<CFP_t> {
return getRX<CFP_t>(params.front());
}
template <class CFP_t, class U = double>
static auto getRY(U angle) -> std::vector<CFP_t> {
const CFP_t c{std::cos(angle / 2), 0};
const CFP_t s{std::sin(angle / 2), 0};
return {c, -s, s, c};
}
template <class CFP_t, class U = double>
static auto getRY(const std::vector<U> ¶ms) -> std::vector<CFP_t> {
return getRY<CFP_t>(params.front());
}
template <class CFP_t, class U = double>
static auto getRZ(U angle) -> std::vector<CFP_t> {
return {{std::cos(-angle / 2), std::sin(-angle / 2)},
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
{std::cos(angle / 2), std::sin(angle / 2)}};
}
template <class CFP_t, class U = double>
static auto getRZ(const std::vector<U> ¶ms) -> std::vector<CFP_t> {
return getRZ<CFP_t>(params.front());
}
template <class CFP_t, class U = double>
static auto getRot(U phi, U theta, U omega) -> std::vector<CFP_t> {
const U c = std::cos(theta / 2);
const U s = std::sin(theta / 2);
const U p{phi + omega};
const U m{phi - omega};
/*
return {CFP_t{std::cos(p / 2), -std::sin(p / 2)} * c,
-CFP_t{std::cos(m / 2), std::sin(m / 2)} * s,
CFP_t{std::cos(m / 2), -std::sin(m / 2)} * s,
CFP_t{std::cos(p / 2), std::sin(p / 2)} * c};*/
return {ConstMultSC(c, CFP_t{std::cos(p / 2), -std::sin(p / 2)}),
ConstMultSC(s, -CFP_t{std::cos(m / 2), std::sin(m / 2)}),
ConstMultSC(s, CFP_t{std::cos(m / 2), -std::sin(m / 2)}),
ConstMultSC(c, CFP_t{std::cos(p / 2), std::sin(p / 2)})};
}
template <class CFP_t, class U = double>
static auto getRot(const std::vector<U> ¶ms) -> std::vector<CFP_t> {
return getRot<CFP_t>(params[0], params[1], params[2]);
}
template <class CFP_t, class U = double>
static auto getCRX(U angle) -> std::vector<CFP_t> {
const auto rx{getRX<CFP_t>(angle)};
return {cuUtil::ONE<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
cuUtil::ONE<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
rx[0],
rx[1],
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
rx[2],
rx[3]};
}
template <class CFP_t, class U = double>
static auto getCRX(const std::vector<U> ¶ms) -> std::vector<CFP_t> {
return getCRX<CFP_t>(params.front());
}
template <class CFP_t, class U = double>
static auto getCRY(U angle) -> std::vector<CFP_t> {
const auto ry{getRY<CFP_t>(angle)};
return {cuUtil::ONE<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
cuUtil::ONE<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
ry[0],
ry[1],
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
ry[2],
ry[3]};
}
template <class CFP_t, class U = double>
static auto getCRY(const std::vector<U> ¶ms) -> std::vector<CFP_t> {
return getCRY<CFP_t>(params.front());
}
template <class CFP_t, class U = double>
static auto getCRZ(U angle) -> std::vector<CFP_t> {
const CFP_t first{std::cos(-angle / 2), std::sin(-angle / 2)};
const CFP_t second{std::cos(angle / 2), std::sin(angle / 2)};
return {cuUtil::ONE<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
cuUtil::ONE<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
first,
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
second};
}
template <class CFP_t, class U = double>
static auto getCRZ(const std::vector<U> ¶ms) -> std::vector<CFP_t> {
return getCRZ<CFP_t>(params.front());
}
template <class CFP_t, class U = double>
static auto getCRot(U phi, U theta, U omega) -> std::vector<CFP_t> {
const auto rot{std::move(getRot<CFP_t>(phi, theta, omega))};
return {cuUtil::ONE<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
cuUtil::ONE<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
rot[0],
rot[1],
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
rot[2],
rot[3]};
}
template <class CFP_t, class U = double>
static auto getCRot(const std::vector<U> ¶ms) -> std::vector<CFP_t> {
return getCRot<CFP_t>(params[0], params[1], params[2]);
}
template <class CFP_t, class U = double>
static auto getControlledPhaseShift(U angle) -> std::vector<CFP_t> {
return {cuUtil::ONE<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ONE<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ONE<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), {std::cos(angle), std::sin(angle)}};
}
template <class CFP_t, class U = double>
static auto getControlledPhaseShift(const std::vector<U> ¶ms)
-> std::vector<CFP_t> {
return getControlledPhaseShift<CFP_t>(params.front());
}
template <class CFP_t, class U = double>
static auto getSingleExcitation(U angle) -> std::vector<CFP_t> {
const U p2 = angle / 2;
const CFP_t c{std::cos(p2), 0};
// TODO: To remove conditional compilation here in the future, current
// implementation will block the simultaneous installation of LGPU and
// cutensornet backends
#ifdef _ENABLE_PLGPU
const CFP_t s{-std::sin(p2), 0}; // column-major
#else
const CFP_t s{std::sin(p2), 0}; // row-major
#endif
return {cuUtil::ONE<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
c,
-s,
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
s,
c,
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
cuUtil::ONE<CFP_t>()};
}
template <class CFP_t, class U = double>
static auto getSingleExcitation(const std::vector<U> ¶ms)
-> std::vector<CFP_t> {
return getSingleExcitation<CFP_t>(params.front());
}
template <class CFP_t, class U = double>
static constexpr auto getGeneratorSingleExcitation() -> std::vector<CFP_t> {
return {
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::IMAG<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), -cuUtil::IMAG<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
};
}
template <class CFP_t, class U = double>
static auto getSingleExcitationMinus(U angle) -> std::vector<CFP_t> {
const U p2 = angle / 2;
const CFP_t e =
cuUtil::complexToCu<std::complex<U>>(std::exp(std::complex<U>(0, -p2)));
const CFP_t c{std::cos(p2), 0};
// TODO: To remove conditional compilation here in the future, current
// implementation will block the simultaneous installation of LGPU and
// cutensornet backends
#ifdef _ENABLE_PLGPU
const CFP_t s{-std::sin(p2), 0}; // column-major
#else
const CFP_t s{std::sin(p2), 0}; // row-major
#endif
return {e,
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
c,
-s,
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
s,
c,
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
e};
}
template <class CFP_t, class U = double>
static auto getSingleExcitationMinus(const std::vector<U> ¶ms)
-> std::vector<CFP_t> {
return getSingleExcitationMinus<CFP_t>(params.front());
}
template <class CFP_t, class U = double>
static constexpr auto getGeneratorSingleExcitationMinus()
-> std::vector<CFP_t> {
return {
cuUtil::ONE<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::IMAG<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), -cuUtil::IMAG<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ONE<CFP_t>(),
};
}
template <class CFP_t, class U = double>
static auto getSingleExcitationPlus(U angle) -> std::vector<CFP_t> {
const U p2 = angle / 2;
const CFP_t e =
cuUtil::complexToCu<std::complex<U>>(std::exp(std::complex<U>(0, p2)));
const CFP_t c{std::cos(p2), 0};
// TODO: To remove conditional compilation here in the future, current
// implementation will block the simultaneous installation of LGPU and
// cutensornet backends
#ifdef _ENABLE_PLGPU
const CFP_t s{-std::sin(p2), 0}; // column-major
#else
const CFP_t s{std::sin(p2), 0}; // row-major
#endif
return {e,
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
c,
-s,
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
s,
c,
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
e};
}
template <class CFP_t, class U = double>
static auto getSingleExcitationPlus(const std::vector<U> ¶ms)
-> std::vector<CFP_t> {
return getSingleExcitationPlus<CFP_t>(params.front());
}
template <class CFP_t, class U = double>
static constexpr auto getGeneratorSingleExcitationPlus() -> std::vector<CFP_t> {
return {
-cuUtil::ONE<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::IMAG<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), -cuUtil::IMAG<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), -cuUtil::ONE<CFP_t>(),
};
}
template <class CFP_t, class U = double>
static auto getDoubleExcitation(U angle) -> std::vector<CFP_t> {
const U p2 = angle / 2;
const CFP_t c{std::cos(p2), 0};
// TODO: To remove conditional compilation here in the future, current
// implementation will block the simultaneous installation of LGPU and
// cutensornet backends
#ifdef _ENABLE_PLGPU
const CFP_t s{-std::sin(p2), 0}; // column-major
#else
const CFP_t s{std::sin(p2), 0}; // row-major
#endif
std::vector<CFP_t> mat(256, cuUtil::ZERO<CFP_t>());
mat[0] = cuUtil::ONE<CFP_t>();
mat[17] = cuUtil::ONE<CFP_t>();
mat[34] = cuUtil::ONE<CFP_t>();
mat[51] = c;
mat[60] = -s;
mat[68] = cuUtil::ONE<CFP_t>();
mat[85] = cuUtil::ONE<CFP_t>();
mat[102] = cuUtil::ONE<CFP_t>();
mat[119] = cuUtil::ONE<CFP_t>();
mat[136] = cuUtil::ONE<CFP_t>();
mat[153] = cuUtil::ONE<CFP_t>();
mat[170] = cuUtil::ONE<CFP_t>();
mat[187] = cuUtil::ONE<CFP_t>();
mat[195] = s;
mat[204] = c;
mat[221] = cuUtil::ONE<CFP_t>();
mat[238] = cuUtil::ONE<CFP_t>();
mat[255] = cuUtil::ONE<CFP_t>();
return mat;
}
template <class CFP_t, class U = double>
static auto getDoubleExcitation(const std::vector<U> ¶ms)
-> std::vector<CFP_t> {
return getDoubleExcitation<CFP_t>(params.front());
}
template <class CFP_t, class U = double>
static constexpr auto getGeneratorDoubleExcitation() -> std::vector<CFP_t> {
std::vector<CFP_t> mat(256, cuUtil::ZERO<CFP_t>());
mat[60] = cuUtil::IMAG<CFP_t>();
mat[195] = -cuUtil::IMAG<CFP_t>();
return mat;
}
template <class CFP_t, class U = double>
static auto getDoubleExcitationMinus(U angle) -> std::vector<CFP_t> {
const U p2 = angle / 2;
const CFP_t e =
cuUtil::complexToCu<std::complex<U>>(std::exp(std::complex<U>(0, -p2)));
const CFP_t c{std::cos(p2), 0};
// TODO: To remove conditional compilation here in the future, current
// implementation will block the simultaneous installation of LGPU and
// cutensornet backends
#ifdef _ENABLE_PLGPU
const CFP_t s{-std::sin(p2), 0}; // column-major
#else
const CFP_t s{std::sin(p2), 0}; // row-major
#endif
std::vector<CFP_t> mat(256, cuUtil::ZERO<CFP_t>());
mat[0] = e;
mat[17] = e;
mat[34] = e;
mat[51] = c;
mat[60] = -s;
mat[68] = e;
mat[85] = e;
mat[102] = e;
mat[119] = e;
mat[136] = e;
mat[153] = e;
mat[170] = e;
mat[187] = e;
mat[195] = s;
mat[204] = c;
mat[221] = e;
mat[238] = e;
mat[255] = e;
return mat;
}
template <class CFP_t, class U = double>
static auto getDoubleExcitationMinus(const std::vector<U> ¶ms)
-> std::vector<CFP_t> {
return getDoubleExcitationMinus<CFP_t>(params.front());
}
template <class CFP_t, class U = double>
static constexpr auto getGeneratorDoubleExcitationMinus()
-> std::vector<CFP_t> {
std::vector<CFP_t> mat(256, cuUtil::ZERO<CFP_t>());
mat[0] = cuUtil::ONE<CFP_t>();
mat[17] = cuUtil::ONE<CFP_t>();
mat[34] = cuUtil::ONE<CFP_t>();
mat[60] = cuUtil::IMAG<CFP_t>();
mat[68] = cuUtil::ONE<CFP_t>();
mat[85] = cuUtil::ONE<CFP_t>();
mat[102] = cuUtil::ONE<CFP_t>();
mat[119] = cuUtil::ONE<CFP_t>();
mat[136] = cuUtil::ONE<CFP_t>();
mat[153] = cuUtil::ONE<CFP_t>();
mat[170] = cuUtil::ONE<CFP_t>();
mat[187] = cuUtil::ONE<CFP_t>();
mat[195] = -cuUtil::IMAG<CFP_t>();
mat[221] = cuUtil::ONE<CFP_t>();
mat[238] = cuUtil::ONE<CFP_t>();
mat[255] = cuUtil::ONE<CFP_t>();
return mat;
}
template <class CFP_t, class U = double>
static auto getDoubleExcitationPlus(U angle) -> std::vector<CFP_t> {
const U p2 = angle / 2;
const CFP_t e =
cuUtil::complexToCu<std::complex<U>>(std::exp(std::complex<U>(0, p2)));
const CFP_t c{std::cos(p2), 0};
// TODO: To remove conditional compilation here in the future, current
// implementation will block the simultaneous installation of LGPU and
// cutensornet backends
#ifdef _ENABLE_PLGPU
const CFP_t s{-std::sin(p2), 0}; // column-major
#else
const CFP_t s{std::sin(p2), 0}; // row-major
#endif
std::vector<CFP_t> mat(256, cuUtil::ZERO<CFP_t>());
mat[0] = e;
mat[17] = e;
mat[34] = e;
mat[51] = c;
mat[60] = -s;
mat[68] = e;
mat[85] = e;
mat[102] = e;
mat[119] = e;
mat[136] = e;
mat[153] = e;
mat[170] = e;
mat[187] = e;
mat[195] = s;
mat[204] = c;
mat[221] = e;
mat[238] = e;
mat[255] = e;
return mat;
}
template <class CFP_t, class U = double>
static auto getDoubleExcitationPlus(const std::vector<U> ¶ms)
-> std::vector<CFP_t> {
return getDoubleExcitationPlus<CFP_t>(params.front());
}
template <class CFP_t, class U = double>
static constexpr auto getGeneratorDoubleExcitationPlus() -> std::vector<CFP_t> {
std::vector<CFP_t> mat(256, cuUtil::ZERO<CFP_t>());
mat[0] = -cuUtil::ONE<CFP_t>();
mat[17] = -cuUtil::ONE<CFP_t>();
mat[34] = -cuUtil::ONE<CFP_t>();
mat[60] = cuUtil::IMAG<CFP_t>();
mat[68] = -cuUtil::ONE<CFP_t>();
mat[85] = -cuUtil::ONE<CFP_t>();
mat[102] = -cuUtil::ONE<CFP_t>();
mat[119] = -cuUtil::ONE<CFP_t>();
mat[136] = -cuUtil::ONE<CFP_t>();
mat[153] = -cuUtil::ONE<CFP_t>();
mat[170] = -cuUtil::ONE<CFP_t>();
mat[187] = -cuUtil::ONE<CFP_t>();
mat[195] = -cuUtil::IMAG<CFP_t>();
mat[221] = -cuUtil::ONE<CFP_t>();
mat[238] = -cuUtil::ONE<CFP_t>();
mat[255] = -cuUtil::ONE<CFP_t>();
return mat;
}
template <class CFP_t, class U = double>
static auto getIsingXX(U angle) -> std::vector<CFP_t> {
const U p2 = angle / 2;
const CFP_t c{std::cos(p2), 0};
const CFP_t neg_is{0, -std::sin(p2)};
return {c,
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
neg_is,
cuUtil::ZERO<CFP_t>(),
c,
neg_is,
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
neg_is,
c,
cuUtil::ZERO<CFP_t>(),
neg_is,
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
c};
}
template <class CFP_t, class U = double>
static auto getIsingXX(const std::vector<U> ¶ms) -> std::vector<CFP_t> {
return getIsingXX<CFP_t>(params.front());
}
template <class CFP_t, class U = double>
static constexpr auto getGeneratorIsingXX() -> std::vector<CFP_t> {
return {
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ONE<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ONE<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ONE<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ONE<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
};
}
template <class CFP_t, class U = double>
static auto getIsingYY(U angle) -> std::vector<CFP_t> {
const U p2 = angle / 2;
const CFP_t c{std::cos(p2), 0};
const CFP_t pos_is{0, std::sin(p2)};
const CFP_t neg_is{0, -std::sin(p2)};
return {c,
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
pos_is,
cuUtil::ZERO<CFP_t>(),
c,
neg_is,
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
neg_is,
c,
cuUtil::ZERO<CFP_t>(),
pos_is,
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
c};
}
template <class CFP_t, class U = double>
static auto getIsingYY(const std::vector<U> ¶ms) -> std::vector<CFP_t> {
return getIsingYY<CFP_t>(params.front());
}
template <class CFP_t, class U = double>
static constexpr auto getGeneratorIsingYY() -> std::vector<CFP_t> {
return {
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), -cuUtil::ONE<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ONE<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ONE<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
-cuUtil::ONE<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
};
}
template <class CFP_t, class U = double>
static auto getIsingZZ(U angle) -> std::vector<CFP_t> {
const U p2 = angle / 2;
const CFP_t neg_e =
cuUtil::complexToCu<std::complex<U>>(std::exp(std::complex<U>(0, -p2)));
const CFP_t pos_e =
cuUtil::complexToCu<std::complex<U>>(std::exp(std::complex<U>(0, p2)));
return {neg_e,
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
pos_e,
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
pos_e,
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
neg_e};
}
template <class CFP_t, class U = double>
static auto getIsingZZ(const std::vector<U> ¶ms) -> std::vector<CFP_t> {
return getIsingZZ<CFP_t>(params.front());
}
template <class CFP_t, class U = double>
static constexpr auto getGeneratorIsingZZ() -> std::vector<CFP_t> {
return {
cuUtil::ONE<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), -cuUtil::ONE<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
-cuUtil::ONE<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ONE<CFP_t>(),
};
}
template <class CFP_t, class U = double>
static auto getIsingXY(U angle) -> std::vector<CFP_t> {
const U p2 = angle / 2;
const CFP_t c{std::cos(p2), 0};
const CFP_t pos_is{0, std::sin(p2)};
return {cuUtil::ONE<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
c,
pos_is,
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
pos_is,
c,
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(),
cuUtil::ONE<CFP_t>()};
}
template <class CFP_t, class U = double>
static auto getIsingXY(const std::vector<U> ¶ms) -> std::vector<CFP_t> {
return getIsingXY<CFP_t>(params.front());
}
template <class CFP_t, class U = double>
static constexpr auto getGeneratorIsingXY() -> std::vector<CFP_t> {
return {
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ONE<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ONE<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
};
}
template <class CFP_t> static constexpr auto getP11_CU() -> std::vector<CFP_t> {
return {cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ONE<CFP_t>()};
}
template <class CFP_t>
static constexpr auto getP1111_CU() -> std::vector<CFP_t> {
return {cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(), cuUtil::ZERO<CFP_t>(),
cuUtil::ONE<CFP_t>()};
}
template <class CFP_t> static constexpr auto getXY() -> std::vector<CFP_t> {
auto &&PauliY = getPauliY<CFP_t>();
return {PauliY[2], PauliY[3], PauliY[0], PauliY[1]};
}
template <class CFP_t> static constexpr auto getXZ() -> std::vector<CFP_t> {
auto &&PauliZ = getPauliZ<CFP_t>();
return {PauliZ[2], PauliZ[3], PauliZ[0], PauliZ[1]};
}
template <class CFP_t> static constexpr auto getXH() -> std::vector<CFP_t> {
auto &&Hadamard = getHadamard<CFP_t>();
return {Hadamard[2], Hadamard[3], Hadamard[0], Hadamard[1]};
}
template <class CFP_t> static constexpr auto getYX() -> std::vector<CFP_t> {
auto &&PauliY = getPauliY<CFP_t>();
return {PauliY[1], PauliY[0], PauliY[3], PauliY[2]};
}
template <class CFP_t> static constexpr auto getZX() -> std::vector<CFP_t> {
auto &&PauliZ = getPauliZ<CFP_t>();
return {PauliZ[1], PauliZ[0], PauliZ[3], PauliZ[2]};
}
template <class CFP_t> static constexpr auto getHX() -> std::vector<CFP_t> {
auto &&Hadamard = getHadamard<CFP_t>();
return {Hadamard[1], Hadamard[0], Hadamard[3], Hadamard[2]};
}
template <class CFP_t> static constexpr auto getYZ() -> std::vector<CFP_t> {
auto &&PauliY = getPauliY<CFP_t>();
return {PauliY[0], -PauliY[1], PauliY[2], -PauliY[3]};
}
template <class CFP_t> static constexpr auto getYH() -> std::vector<CFP_t> {
return {-cuUtil::INVSQRT2IMAG<CFP_t>(), cuUtil::INVSQRT2IMAG<CFP_t>(),
cuUtil::INVSQRT2IMAG<CFP_t>(), cuUtil::INVSQRT2IMAG<CFP_t>()};
}
template <class CFP_t> static constexpr auto getZY() -> std::vector<CFP_t> {
auto &&PauliY = getPauliY<CFP_t>();
return {PauliY[0], PauliY[1], -PauliY[2], -PauliY[3]};
}
template <class CFP_t> static constexpr auto getZH() -> std::vector<CFP_t> {
auto &&Hadamard = getHadamard<CFP_t>();
return {Hadamard[0], Hadamard[1], -Hadamard[2], -Hadamard[3]};
}
template <class CFP_t> static constexpr auto getHY() -> std::vector<CFP_t> {
return {cuUtil::INVSQRT2IMAG<CFP_t>(), -cuUtil::INVSQRT2IMAG<CFP_t>(),
-cuUtil::INVSQRT2IMAG<CFP_t>(), -cuUtil::INVSQRT2IMAG<CFP_t>()};
}
template <class CFP_t> static constexpr auto getHZ() -> std::vector<CFP_t> {
auto &&Hadamard = getHadamard<CFP_t>();
return {Hadamard[0], -Hadamard[1], Hadamard[2], -Hadamard[3]};
}
/*
* @brief Dyanmical access the gate data based on the gate name and parameters.
*
* @tparam PrecisionT Required precision of gate (`float` or `double`).
*/
template <class PrecisionT> class DynamicGateDataAccess {
private:
DynamicGateDataAccess() = default;
public:
using CFP_t = decltype(cuUtil::getCudaType(PrecisionT{}));
DynamicGateDataAccess(DynamicGateDataAccess &&) = delete;
DynamicGateDataAccess(const DynamicGateDataAccess &) = delete;
DynamicGateDataAccess &operator=(const DynamicGateDataAccess &) = delete;
~DynamicGateDataAccess() = default;
public:
static DynamicGateDataAccess &getInstance() {
static DynamicGateDataAccess instance;
return instance;
}
auto
getGateData(const std::string &gate_name,
[[maybe_unused]] const std::vector<PrecisionT> ¶ms) const
-> std::vector<CFP_t> {
if (nonparametric_gates_.find(gate_name) !=
nonparametric_gates_.end()) {
return nonparametric_gates_.at(gate_name)();
} else if (parametric_gates_.find(gate_name) !=
parametric_gates_.end()) {
return parametric_gates_.at(gate_name)(params);
} else {
throw std::invalid_argument("Unsupported gate: " + gate_name + ".");
}
}
private:
using ParamGateFunc =
std::function<std::vector<CFP_t>(const std::vector<PrecisionT> &)>;
using NonParamGateFunc = std::function<std::vector<CFP_t>()>;
using ParamGateFuncMap = std::unordered_map<std::string, ParamGateFunc>;
using NonParamGateFuncMap =
std::unordered_map<std::string, NonParamGateFunc>;
// TODO: Need changes to support to the controlled gate tensor API once the
// API is finalized in cutensornet lib.
NonParamGateFuncMap nonparametric_gates_{
{"Identity",
[]() -> std::vector<CFP_t> { return cuGates::getIdentity<CFP_t>(); }},
{"PauliX",
[]() -> std::vector<CFP_t> { return cuGates::getPauliX<CFP_t>(); }},
{"PauliY",
[]() -> std::vector<CFP_t> { return cuGates::getPauliY<CFP_t>(); }},
{"PauliZ",
[]() -> std::vector<CFP_t> { return cuGates::getPauliZ<CFP_t>(); }},
{"S", []() -> std::vector<CFP_t> { return cuGates::getS<CFP_t>(); }},
{"Hadamard",
[]() -> std::vector<CFP_t> { return cuGates::getHadamard<CFP_t>(); }},
{"T", []() -> std::vector<CFP_t> { return cuGates::getT<CFP_t>(); }},
{"SWAP",
[]() -> std::vector<CFP_t> { return cuGates::getSWAP<CFP_t>(); }},
{"CNOT",
[]() -> std::vector<CFP_t> { return cuGates::getCNOT<CFP_t>(); }},
{"Toffoli",
[]() -> std::vector<CFP_t> { return cuGates::getToffoli<CFP_t>(); }},
{"CY", []() -> std::vector<CFP_t> { return cuGates::getCY<CFP_t>(); }},
{"CZ", []() -> std::vector<CFP_t> { return cuGates::getCZ<CFP_t>(); }},
{"I@I",
[]() -> std::vector<CFP_t> { return cuGates::getIdentity<CFP_t>(); }},
{"I@X",
[]() -> std::vector<CFP_t> { return cuGates::getPauliX<CFP_t>(); }},
{"I@Y",
[]() -> std::vector<CFP_t> { return cuGates::getPauliY<CFP_t>(); }},
{"I@Z",
[]() -> std::vector<CFP_t> { return cuGates::getPauliZ<CFP_t>(); }},
{"I@H",
[]() -> std::vector<CFP_t> { return cuGates::getHadamard<CFP_t>(); }},
{"X@I",
[]() -> std::vector<CFP_t> { return cuGates::getPauliX<CFP_t>(); }},
{"X@X",
[]() -> std::vector<CFP_t> { return cuGates::getIdentity<CFP_t>(); }},
{"X@Y", []() -> std::vector<CFP_t> { return cuGates::getXY<CFP_t>(); }},
{"X@Z", []() -> std::vector<CFP_t> { return cuGates::getXZ<CFP_t>(); }},
{"X@H", []() -> std::vector<CFP_t> { return cuGates::getXH<CFP_t>(); }},
{"Y@I",
[]() -> std::vector<CFP_t> { return cuGates::getPauliY<CFP_t>(); }},
{"Y@X", []() -> std::vector<CFP_t> { return cuGates::getYX<CFP_t>(); }},
{"Y@Y",
[]() -> std::vector<CFP_t> { return cuGates::getIdentity<CFP_t>(); }},
{"Y@Z", []() -> std::vector<CFP_t> { return cuGates::getYZ<CFP_t>(); }},
{"Y@H", []() -> std::vector<CFP_t> { return cuGates::getYH<CFP_t>(); }},
{"Z@I",
[]() -> std::vector<CFP_t> { return cuGates::getPauliZ<CFP_t>(); }},
{"Z@X", []() -> std::vector<CFP_t> { return cuGates::getZX<CFP_t>(); }},
{"Z@Y", []() -> std::vector<CFP_t> { return cuGates::getZY<CFP_t>(); }},
{"Z@Z",
[]() -> std::vector<CFP_t> { return cuGates::getIdentity<CFP_t>(); }},
{"Z@H", []() -> std::vector<CFP_t> { return cuGates::getZH<CFP_t>(); }},
{"H@I",
[]() -> std::vector<CFP_t> { return cuGates::getHadamard<CFP_t>(); }},
{"H@X", []() -> std::vector<CFP_t> { return cuGates::getHX<CFP_t>(); }},
{"H@Y", []() -> std::vector<CFP_t> { return cuGates::getHY<CFP_t>(); }},
{"H@Z", []() -> std::vector<CFP_t> { return cuGates::getHZ<CFP_t>(); }},
{"H@H",
[]() -> std::vector<CFP_t> { return cuGates::getIdentity<CFP_t>(); }},
{"CSWAP",
[]() -> std::vector<CFP_t> { return cuGates::getCSWAP<CFP_t>(); }}};
// TODO: Need changes to support to the controlled gate tensor API once the
// API is finalized in cutensornet lib.
ParamGateFuncMap parametric_gates_{
{"PhaseShift",
[](auto &¶ms) {
return cuGates::getPhaseShift<CFP_t>(
std::forward<decltype(params[0])>(params[0]));
}},
{"RX",
[](auto &¶ms) {
return cuGates::getRX<CFP_t>(
std::forward<decltype(params[0])>(params[0]));
}},
{"RY",
[](auto &¶ms) {
return cuGates::getRY<CFP_t>(
std::forward<decltype(params[0])>(params[0]));
}},
{"RZ",
[](auto &¶ms) {
return cuGates::getRZ<CFP_t>(
std::forward<decltype(params[0])>(params[0]));
}},
{"Rot",
[](auto &¶ms) {
return cuGates::getRot<CFP_t>(
std::forward<decltype(params[0])>(params[0]),
std::forward<decltype(params[1])>(params[1]),
std::forward<decltype(params[2])>(params[2]));
}},
{"CRX",
[](auto &¶ms) {
return cuGates::getCRX<CFP_t>(
std::forward<decltype(params[0])>(params[0]));
}},
{"CRY",
[](auto &¶ms) {
return cuGates::getCRY<CFP_t>(
std::forward<decltype(params[0])>(params[0]));
}},
{"CRZ",
[](auto &¶ms) {
return cuGates::getCRZ<CFP_t>(
std::forward<decltype(params[0])>(params[0]));
}},
{"CRot",
[](auto &¶ms) {
return cuGates::getCRot<CFP_t>(
std::forward<decltype(params[0])>(params[0]),
std::forward<decltype(params[1])>(params[1]),
std::forward<decltype(params[2])>(params[2]));
}},
{"ControlledPhaseShift",
[](auto &¶ms) {
return cuGates::getControlledPhaseShift<CFP_t>(
std::forward<decltype(params[0])>(params[0]));
}},
{"IsingXX",
[](auto &¶ms) {
return cuGates::getIsingXX<CFP_t>(
std::forward<decltype(params[0])>(params[0]));
}},
{"IsingYY",
[](auto &¶ms) {
return cuGates::getIsingYY<CFP_t>(
std::forward<decltype(params[0])>(params[0]));
}},
{"IsingZZ",
[](auto &¶ms) {
return cuGates::getIsingZZ<CFP_t>(
std::forward<decltype(params[0])>(params[0]));
}},
{"IsingXY",
[](auto &¶ms) {
return cuGates::getIsingXY<CFP_t>(
std::forward<decltype(params[0])>(params[0]));
}},
{"SingleExcitation",
[](auto &¶ms) {
return cuGates::getSingleExcitation<CFP_t>(
std::forward<decltype(params[0])>(params[0]));
}},
{"SingleExcitationMinus",
[](auto &¶ms) {
return cuGates::getSingleExcitationMinus<CFP_t>(
std::forward<decltype(params[0])>(params[0]));
}},
{"SingleExcitationPlus",
[](auto &¶ms) {
return cuGates::getSingleExcitationPlus<CFP_t>(
std::forward<decltype(params[0])>(params[0]));
}},
{"DoubleExcitation",
[](auto &¶ms) {
return cuGates::getDoubleExcitation<CFP_t>(
std::forward<decltype(params[0])>(params[0]));
}},
{"DoubleExcitationMinus",
[](auto &¶ms) {
return cuGates::getDoubleExcitationMinus<CFP_t>(
std::forward<decltype(params[0])>(params[0]));
}},
{"DoubleExcitationPlus", [](auto &¶ms) {
return cuGates::getDoubleExcitationPlus<CFP_t>(
std::forward<decltype(params[0])>(params[0]));
}}};
};
} // namespace Pennylane::LightningGPU::cuGates
api/program_listing_file_pennylane_lightning_core_src_utils_cuda_utils_cuGates_host.hpp
Download Python script
Download Notebook
View on GitHub