-
Notifications
You must be signed in to change notification settings - Fork 40
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Downstream LightningSimulator C++ API to the pennylane-lightning repo…
…sitory (#960) **Context:** Catalyst needs to build a class wrapping the Lightning Qubit class. Here we are moving the logic from Catalyst to the Lightning repository. **Description of the Change:** Moving code from Catalyst to this repository and updating the build system to build against Catalyst. **Benefits:** Catalyst wheels will build faster. **Possible Drawbacks:** Our build system now relies on headers coming from Catalyst. It is unclear if this may cause a deadlock in the future because of our cyclic dependencies (PennyLane, PennyLane Lightning, Catalyst). Chances are small because we don't rely on Catalyst wheels or build it from scratch. [sc-70316] [sc-70318] [sc-70317] --------- Co-authored-by: ringo-but-quantum <[email protected]> Co-authored-by: Lee James O'Riordan <[email protected]> Co-authored-by: paul0403 <[email protected]> Co-authored-by: Haochen Wang <[email protected]> Co-authored-by: Ali Asadi <[email protected]>
- Loading branch information
1 parent
b491a37
commit 4659093
Showing
22 changed files
with
5,062 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,4 +16,4 @@ | |
Version number (major.minor.patch[-label]) | ||
""" | ||
|
||
__version__ = "0.40.0-dev6" | ||
__version__ = "0.40.0-dev7" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
24 changes: 24 additions & 0 deletions
24
pennylane_lightning/core/src/simulators/lightning_qubit/catalyst/CMakeLists.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
cmake_minimum_required(VERSION 3.20) | ||
|
||
project(lightning_qubit_catalyst LANGUAGES CXX) | ||
|
||
set(LQ_CATALYST_FILES LightningSimulator.cpp CACHE INTERNAL "") | ||
add_library(lightning_qubit_catalyst SHARED ${LQ_CATALYST_FILES}) | ||
|
||
include(FetchContent) | ||
|
||
include("${pennylane_lightning_SOURCE_DIR}/cmake/support_catalyst.cmake") | ||
FindCatalyst(lightning_qubit_catalyst) | ||
|
||
target_include_directories(lightning_qubit_catalyst INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) | ||
target_link_libraries(lightning_qubit_catalyst PUBLIC lightning_compile_options | ||
lightning_external_libs | ||
lightning_qubit_algorithms | ||
lightning_qubit_measurements | ||
lightning_qubit_observables | ||
) | ||
|
||
if (BUILD_TESTS) | ||
enable_testing() | ||
add_subdirectory("tests") | ||
endif() |
205 changes: 205 additions & 0 deletions
205
pennylane_lightning/core/src/simulators/lightning_qubit/catalyst/LightningObsManager.hpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,205 @@ | ||
// Copyright 2022 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 <array> | ||
#include <stdexcept> | ||
#include <tuple> | ||
#include <utility> | ||
|
||
#include "Exception.hpp" | ||
#include "Types.h" | ||
#include "Utils.hpp" | ||
|
||
#include "ObservablesLQubit.hpp" | ||
#include "StateVectorLQubitDynamic.hpp" | ||
|
||
namespace { | ||
using Pennylane::LightningQubit::StateVectorLQubitDynamic; | ||
using Pennylane::LightningQubit::Observables::HermitianObs; | ||
using Pennylane::LightningQubit::Observables::NamedObs; | ||
using Pennylane::LightningQubit::Observables::TensorProdObs; | ||
using Pennylane::Observables::Observable; | ||
} // namespace | ||
|
||
namespace Catalyst::Runtime::Simulator { | ||
|
||
/** | ||
* @brief The LightningObsManager caches observables of a program at runtime | ||
* and maps each one to a const unique index (`int64_t`) in the scope | ||
* of the global context manager. | ||
*/ | ||
template <typename PrecisionT> class LightningObsManager { | ||
private: | ||
using VectorStateT = StateVectorLQubitDynamic<PrecisionT>; | ||
using ComplexT = typename VectorStateT::ComplexT; | ||
using ObservablePairType = | ||
std::pair<std::shared_ptr<Observable<VectorStateT>>, ObsType>; | ||
std::vector<ObservablePairType> observables_{}; | ||
|
||
public: | ||
LightningObsManager() = default; | ||
~LightningObsManager() = default; | ||
|
||
LightningObsManager(const LightningObsManager &) = delete; | ||
LightningObsManager &operator=(const LightningObsManager &) = delete; | ||
LightningObsManager(LightningObsManager &&) = delete; | ||
LightningObsManager &operator=(LightningObsManager &&) = delete; | ||
|
||
/** | ||
* @brief A helper function to clear constructed observables in the program. | ||
*/ | ||
void clear() { observables_.clear(); } | ||
|
||
/** | ||
* @brief Check the validity of observable keys. | ||
* | ||
* @param obsKeys The vector of observable keys | ||
* @return bool | ||
*/ | ||
[[nodiscard]] auto | ||
isValidObservables(const std::vector<ObsIdType> &obsKeys) const -> bool { | ||
return std::all_of(obsKeys.begin(), obsKeys.end(), [this](auto i) { | ||
return (i >= 0 && static_cast<size_t>(i) < observables_.size()); | ||
}); | ||
} | ||
|
||
/** | ||
* @brief Get the constructed observable instance. | ||
* | ||
* @param key The observable key | ||
* @return std::shared_ptr<Observable<VectorStateT>> | ||
*/ | ||
[[nodiscard]] auto getObservable(ObsIdType key) | ||
-> std::shared_ptr<Observable<VectorStateT>> { | ||
RT_FAIL_IF(!isValidObservables({key}), "Invalid observable key"); | ||
return std::get<0>(observables_[key]); | ||
} | ||
|
||
/** | ||
* @brief Get the number of observables. | ||
* | ||
* @return size_t | ||
*/ | ||
[[nodiscard]] auto numObservables() const -> size_t { | ||
return observables_.size(); | ||
} | ||
|
||
/** | ||
* @brief Create and cache a new NamedObs instance. | ||
* | ||
* @param obsId The named observable id of type ObsId | ||
* @param wires The vector of wires the observable acts on | ||
* @return ObsIdType | ||
*/ | ||
[[nodiscard]] auto createNamedObs(ObsId obsId, | ||
const std::vector<size_t> &wires) | ||
-> ObsIdType { | ||
auto &&obs_str = std::string( | ||
Lightning::lookup_obs<Lightning::simulator_observable_support_size>( | ||
Lightning::simulator_observable_support, obsId)); | ||
|
||
observables_.push_back(std::make_pair( | ||
std::make_shared<NamedObs<VectorStateT>>(obs_str, wires), | ||
ObsType::Basic)); | ||
return static_cast<ObsIdType>(observables_.size() - 1); | ||
} | ||
|
||
/** | ||
* @brief Create and cache a new HermitianObs instance. | ||
* | ||
* @param matrix The row-wise Hermitian matrix | ||
* @param wires The vector of wires the observable acts on | ||
* @return ObsIdType | ||
*/ | ||
[[nodiscard]] auto createHermitianObs(const std::vector<ComplexT> &matrix, | ||
const std::vector<size_t> &wires) | ||
-> ObsIdType { | ||
observables_.push_back( | ||
std::make_pair(std::make_shared<HermitianObs<VectorStateT>>( | ||
HermitianObs<VectorStateT>{matrix, wires}), | ||
ObsType::Basic)); | ||
|
||
return static_cast<ObsIdType>(observables_.size() - 1); | ||
} | ||
|
||
/** | ||
* @brief Create and cache a new TensorProd instance. | ||
* | ||
* @param obsKeys The vector of observable keys | ||
* @return ObsIdType | ||
*/ | ||
[[nodiscard]] auto | ||
createTensorProdObs(const std::vector<ObsIdType> &obsKeys) -> ObsIdType { | ||
const auto key_size = obsKeys.size(); | ||
const auto obs_size = observables_.size(); | ||
|
||
std::vector<std::shared_ptr<Observable<VectorStateT>>> obs_vec; | ||
obs_vec.reserve(key_size); | ||
|
||
for (const auto &key : obsKeys) { | ||
RT_FAIL_IF(static_cast<size_t>(key) >= obs_size || key < 0, | ||
"Invalid observable key"); | ||
|
||
auto &&[obs, type] = observables_[key]; | ||
obs_vec.push_back(obs); | ||
} | ||
|
||
observables_.push_back(std::make_pair( | ||
TensorProdObs<VectorStateT>::create(obs_vec), ObsType::TensorProd)); | ||
|
||
return static_cast<ObsIdType>(obs_size); | ||
} | ||
|
||
/** | ||
* @brief Create and cache a new HamiltonianObs instance. | ||
* | ||
* @param coeffs The vector of coefficients | ||
* @param obsKeys The vector of observable keys | ||
* @return ObsIdType | ||
*/ | ||
[[nodiscard]] auto | ||
createHamiltonianObs(const std::vector<PrecisionT> &coeffs, | ||
const std::vector<ObsIdType> &obsKeys) -> ObsIdType { | ||
const auto key_size = obsKeys.size(); | ||
const auto obs_size = observables_.size(); | ||
|
||
RT_FAIL_IF( | ||
key_size != coeffs.size(), | ||
"Incompatible list of observables and coefficients; " | ||
"Number of observables and number of coefficients must be equal"); | ||
|
||
std::vector<std::shared_ptr<Observable<VectorStateT>>> obs_vec; | ||
obs_vec.reserve(key_size); | ||
|
||
for (auto key : obsKeys) { | ||
RT_FAIL_IF(static_cast<size_t>(key) >= obs_size || key < 0, | ||
"Invalid observable key"); | ||
|
||
auto &&[obs, type] = observables_[key]; | ||
obs_vec.push_back(obs); | ||
} | ||
|
||
observables_.push_back(std::make_pair( | ||
std::make_shared<Pennylane::LightningQubit::Observables:: | ||
Hamiltonian<VectorStateT>>( | ||
Pennylane::LightningQubit::Observables::Hamiltonian< | ||
VectorStateT>(coeffs, std::move(obs_vec))), | ||
ObsType::Hamiltonian)); | ||
|
||
return static_cast<ObsIdType>(obs_size); | ||
} | ||
}; | ||
} // namespace Catalyst::Runtime::Simulator |
Oops, something went wrong.