Program Listing for File UtilLinearAlg.hpp¶
↰ Return to documentation for file (pennylane_lightning/core/utils/UtilLinearAlg.hpp)
// Copyright 2018-2024 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 <algorithm>
#include <complex>
#include <string>
#include <vector>
#include "Error.hpp"
#ifdef SCIPY_OPENBLAS_ENABLED
#include "BLASLibLoaderManager.hpp"
#endif
namespace {
// Declare heev function pointers to access corresponding functions in
// OpenBLAS
using zheevPtr = void (*)(const char *, const char *, const int *,
std::complex<double> *, const int *, double *,
std::complex<double> *, const int *, double *, int *);
using cheevPtr = void (*)(const char *, const char *, const int *,
std::complex<float> *, const int *, float *,
std::complex<float> *, const int *, float *, int *);
} // namespace
namespace Pennylane::Util {
#ifdef SCIPY_OPENBLAS_ENABLED
template <typename T>
void compute_diagonalizing_gates(int n, int lda,
const std::vector<std::complex<T>> &Ah,
std::vector<T> &eigenVals,
std::vector<std::complex<T>> &unitary) {
auto &&blasLoader = BLASLibLoaderManager::getInstance();
auto *blasLibLoader = blasLoader.getBLASLib();
eigenVals.clear();
eigenVals.resize(n);
unitary = std::vector<std::complex<T>>(n * n, {0, 0});
std::vector<std::complex<T>> ah(n * lda, {0.0, 0.0});
// TODO optmize transpose
for (std::size_t i = 0; i < static_cast<std::size_t>(n); i++) {
for (std::size_t j = 0; j <= i; j++) {
ah[j * n + i] = Ah[i * lda + j];
}
}
constexpr char jobz =
'V'; // Enable both eigenvalues and eigenvectors computation
constexpr char uplo = 'L'; // Upper triangle of matrix is stored
std::vector<std::complex<T>> work_query(1); // Vector for optimal size query
int lwork = -1; // Optimal workspace size query
std::vector<T> rwork(3 * n - 2); // Real workspace array
int info;
if constexpr (std::is_same<T, float>::value) {
auto cheev = blasLibLoader->getSymbol<cheevPtr>("scipy_cheev_");
// Query optimal workspace size
cheev(&jobz, &uplo, &n, ah.data(), &lda, eigenVals.data(),
work_query.data(), &lwork, rwork.data(), &info);
// Allocate workspace
lwork = static_cast<int>(work_query[0].real());
std::vector<std::complex<T>> work_optimal(lwork, {0, 0});
// Perform eigenvalue and eigenvector computation
cheev(&jobz, &uplo, &n, ah.data(), &lda, eigenVals.data(),
work_optimal.data(), &lwork, rwork.data(), &info);
} else {
auto zheev = blasLibLoader->getSymbol<zheevPtr>("scipy_zheev_");
// Query optimal workspace size
zheev(&jobz, &uplo, &n, ah.data(), &lda, eigenVals.data(),
work_query.data(), &lwork, rwork.data(), &info);
// Allocate workspace
lwork = static_cast<int>(work_query[0].real());
std::vector<std::complex<T>> work_optimal(lwork, {0, 0});
// Perform eigenvalue and eigenvector computation
zheev(&jobz, &uplo, &n, ah.data(), &lda, eigenVals.data(),
work_optimal.data(), &lwork, rwork.data(), &info);
}
std::transform(ah.begin(), ah.end(), unitary.begin(),
[](std::complex<T> value) {
return std::complex<T>{value.real(), -value.imag()};
});
}
#else
template <typename T>
void compute_diagonalizing_gates(
[[maybe_unused]] int n, [[maybe_unused]] int lda,
[[maybe_unused]] const std::vector<std::complex<T>> &Ah,
[[maybe_unused]] std::vector<T> &eigenVals,
[[maybe_unused]] std::vector<std::complex<T>> &unitary) {
PL_ABORT("Decompose Hermitian matrix into diagonal matrix and unitaries is "
"only available"
"with scipy-openblas. Consider enabling this feature by setting "
"ENABLE_SCIPY_OPENBLAS.");
}
#endif
} // namespace Pennylane::Util
api/program_listing_file_pennylane_lightning_core_utils_UtilLinearAlg.hpp
Download Python script
Download Notebook
View on GitHub