Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PR #2683 Follow up #2705

Open
wants to merge 92 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
92 commits
Select commit Hold shift + click to select a range
59b584f
Adding cpp integration for dynamics
sacpis Mar 3, 2025
b026c91
Adding missing file dynamics_async_tester
sacpis Mar 3, 2025
b7e7c3d
Checking if vector has any value in methods with optional return type
sacpis Mar 3, 2025
bef5286
Removing optional, fixing unittests
sacpis Mar 3, 2025
b90619b
Adding internal check change
sacpis Mar 3, 2025
88b3f48
Fixing spell check
sacpis Mar 3, 2025
24d867a
Adding examples
sacpis Mar 3, 2025
a672149
Fixing spelling
sacpis Mar 3, 2025
b083add
Adding a descriptive message
sacpis Mar 3, 2025
3a33622
Update runtime/common/EvolveResult.h
sacpis Mar 3, 2025
ad9d6f7
Formatting
sacpis Mar 3, 2025
82e693f
removing rydberg test
sacpis Mar 3, 2025
61f3a64
Removing unwanted check for --target for Python version
sacpis Mar 3, 2025
24308de
Removing std::move from the return statement to allow the compiler to…
sacpis Mar 3, 2025
cba0881
Excluding *.cpp files from dynamics
sacpis Mar 3, 2025
da4fe7d
Passing the states as const &
sacpis Mar 3, 2025
fb71004
Including cudensitymat dir as public
sacpis Mar 4, 2025
8c4ad6f
Fix DynamicsAsyncTester
1tnguyen Mar 3, 2025
6113d40
Inclduing public CUDA toolkit directory
sacpis Mar 4, 2025
145c055
Adding cublas for test_dynamics
sacpis Mar 4, 2025
5044fb9
Adding cutensorlib
sacpis Mar 4, 2025
30e2914
Adding a default constructor for the Schedule class which takes in ve…
sacpis Mar 4, 2025
1d0e714
Updating comments
sacpis Mar 4, 2025
a616205
Adding cublas and cutensor
sacpis Mar 4, 2025
50abd23
changing cudart_static to cudart to avoid linking libnvqir-dynamics t…
sacpis Mar 4, 2025
bdf8d44
Adding cpp integration for dynamics
sacpis Mar 3, 2025
b28fffb
Adding missing file dynamics_async_tester
sacpis Mar 3, 2025
df06f9f
Checking if vector has any value in methods with optional return type
sacpis Mar 3, 2025
770e35c
Removing optional, fixing unittests
sacpis Mar 3, 2025
b09ffe7
Adding internal check change
sacpis Mar 3, 2025
28c0e87
Fixing spell check
sacpis Mar 3, 2025
cd84ebd
Adding examples
sacpis Mar 3, 2025
1b83722
Fixing spelling
sacpis Mar 3, 2025
9ab74b8
Adding a descriptive message
sacpis Mar 3, 2025
7eb8a03
Update runtime/common/EvolveResult.h
sacpis Mar 3, 2025
14b12a4
Formatting
sacpis Mar 3, 2025
e086582
removing rydberg test
sacpis Mar 3, 2025
f5ca416
Removing unwanted check for --target for Python version
sacpis Mar 3, 2025
1ed0765
Removing std::move from the return statement to allow the compiler to…
sacpis Mar 3, 2025
3ccc8ca
Excluding *.cpp files from dynamics
sacpis Mar 3, 2025
c699d8b
Passing the states as const &
sacpis Mar 3, 2025
6137ff6
Including cudensitymat dir as public
sacpis Mar 4, 2025
260acc5
Fix DynamicsAsyncTester
1tnguyen Mar 3, 2025
0bf04c5
Inclduing public CUDA toolkit directory
sacpis Mar 4, 2025
3a401bd
Adding cublas for test_dynamics
sacpis Mar 4, 2025
cfd627f
Adding cutensorlib
sacpis Mar 4, 2025
3a596c2
Adding a default constructor for the Schedule class which takes in ve…
sacpis Mar 4, 2025
c05e272
Updating comments
sacpis Mar 4, 2025
7580bad
Adding cublas and cutensor
sacpis Mar 4, 2025
58f29c0
changing cudart_static to cudart to avoid linking libnvqir-dynamics t…
sacpis Mar 4, 2025
4759ed7
Skipping libnvqir-dynamics validation as one of its dependencies cont…
sacpis Mar 4, 2025
de10c30
Merge branch 'dynamics_cpp_integration' of github.com:sacpis/cuda-qua…
1tnguyen Mar 4, 2025
bf34576
Code refactor according to spec
1tnguyen Mar 4, 2025
4c8fdde
Merge branch 'main' into dynamics_cpp_integration
sacpis Mar 5, 2025
6f7a413
Accepting cudaq::dimensions_map instead of std::map
sacpis Mar 5, 2025
9e32b5f
Merge remote-tracking branch 'origin/dynamics_cpp_integration' into d…
sacpis Mar 5, 2025
b5b91ba
Fix integrator class according to spec review: snake case for public …
1tnguyen Mar 5, 2025
5c6e2b6
* Updating the evolve API signature using concepts (requires clause) to
sacpis Mar 5, 2025
94bb9e4
Formatting
sacpis Mar 5, 2025
3c299fe
Merge branch 'main' into dynamics_cpp_integration
sacpis Mar 5, 2025
6015f4c
Updating type of additional value in the comment
sacpis Mar 5, 2025
37749ca
Adding type constraint for remaining evolve APIs
sacpis Mar 5, 2025
7b0acff
Refactor runge_kutta
1tnguyen Mar 5, 2025
8367d9f
Add gpu_required label to dynamics C++ tests
1tnguyen Mar 6, 2025
0b8c5ee
* Making Schedule class name snake case
sacpis Mar 6, 2025
be2d763
Fixing parameter type
sacpis Mar 6, 2025
04b32e2
Merge remote-tracking branch 'origin/dynamics_cpp_integration' into d…
sacpis Mar 6, 2025
a6fa8e3
Fixing path to exclude
sacpis Mar 6, 2025
894f363
Merge branch 'main' into dynamics_cpp_integration
sacpis Mar 6, 2025
1ddee3c
Adding SFINAE for evolve API
sacpis Mar 6, 2025
90faa72
Merge branch 'main' into dynamics_cpp_integration
sacpis Mar 6, 2025
ed58c02
Keeping the return value as optional for evolve_result
sacpis Mar 6, 2025
63d0f4a
Merge remote-tracking branch 'origin/dynamics_cpp_integration' into d…
sacpis Mar 6, 2025
9bbb3bb
Checking for C++ version to use requires or std::enable_if_t
sacpis Mar 6, 2025
2452c51
Implementing feedback
sacpis Mar 6, 2025
2b793ab
* Updating template constarint for C++20
sacpis Mar 6, 2025
bcdcf52
Merge branch 'main' into dynamics_cpp_integration
sacpis Mar 6, 2025
07a5137
* Removing cpp dynamics examples from the exclusion list
sacpis Mar 6, 2025
1503b9b
* Removing getters as per the spec for dynamics
sacpis Mar 6, 2025
f9d3f15
Enabling dynamics tests for validation
sacpis Mar 7, 2025
1e77767
Merge remote-tracking branch 'origin/dynamics_cpp_integration' into d…
sacpis Mar 7, 2025
b0ff238
Fixing the filter for dynamics tests
sacpis Mar 7, 2025
cadf07b
Merge branch 'main' into dynamics_cpp_follow_up
sacpis Mar 7, 2025
b4445b5
Fixing syntax error
sacpis Mar 7, 2025
94ac594
adding bracket to use ||
sacpis Mar 7, 2025
5d9e7a4
Adding credits for CUDA helpers methods
sacpis Mar 7, 2025
27d11f5
Merge branch 'main' into dynamics_cpp_follow_up
sacpis Mar 7, 2025
bb09f6a
Skipping dynamics examples for non-dynamics targets
sacpis Mar 7, 2025
f9b9407
Fixing syntax
sacpis Mar 7, 2025
b1b25e0
* Fixed validation script to allow dynamics examples in publishing
sacpis Mar 7, 2025
5a82cbe
Merge branch 'main' into dynamics_cpp_follow_up
sacpis Mar 8, 2025
f1420d2
Merge branch 'main' into dynamics_cpp_follow_up
sacpis Mar 8, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .github/workflows/publishing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -839,11 +839,10 @@ jobs:
- name: Basic validation (GPU backends)
shell: bash
run: |
# We don't test the 'dynamics' target in these tests
backends_to_test=`\
for file in $(ls $CUDA_QUANTUM_PATH/targets/*.yml); \
do
if [[ "$file" != *"dynamics"* ]] && [ -n "$(cat $file | grep "gpu-requirements")" ]; then \
if [ -n "$(cat $file | grep "gpu-requirements")" ]; then \
basename $file | cut -d "." -f 1; \
elif [ -n "$(basename $file | grep mqpu)" ]; then \
echo remote-mqpu; \
Expand Down
2 changes: 1 addition & 1 deletion docs/sphinx/examples/cpp/dynamics/cavity_qed.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ int main() {
auto get_expectation = [](int idx, auto &result) -> std::vector<double> {
std::vector<double> expectations;

auto all_exps = result.get_expectation_values().value();
auto all_exps = result.expectation_values.value();
for (auto exp_vals : all_exps) {
expectations.push_back((double)exp_vals[idx]);
}
Expand Down
2 changes: 1 addition & 1 deletion docs/sphinx/examples/cpp/dynamics/cross_resonance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ int main() {
auto get_expectation = [](int idx, auto &result) -> std::vector<double> {
std::vector<double> expectations;

auto all_exps = result.get_expectation_values().value();
auto all_exps = result.expectation_values.value();
for (auto exp_vals : all_exps) {
expectations.push_back((double)exp_vals[idx]);
}
Expand Down
2 changes: 1 addition & 1 deletion docs/sphinx/examples/cpp/dynamics/heisenberg_model.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ int main() {
auto get_expectation = [](int idx, auto &result) -> std::vector<double> {
std::vector<double> expectations;

auto all_exps = result.get_expectation_values().value();
auto all_exps = result.expectation_values.value();
for (auto exp_vals : all_exps) {
expectations.push_back((double)exp_vals[idx]);
}
Expand Down
7 changes: 3 additions & 4 deletions docs/sphinx/examples/cpp/dynamics/qubit_control.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,8 @@ int main() {
// 2. A time-dependent driving term: omega_x * cos(omega_drive * t) * `Sx`_0,
// which induces rotations about the X-axis. The scalar_operator(mod_`func`)
// allows the drive term to vary in time according to mod_`func`.
auto hamiltonian =
0.5 * omega_z * cudaq::spin_operator::z(0) +
omega_x * cudaq::scalar_operator(mod_func) * cudaq::spin_operator::x(0);
auto hamiltonian = 0.5 * omega_z * cudaq::spin_operator::z(0) +
mod_func * cudaq::spin_operator::x(0) * omega_x;

// A single qubit with dimension 2.
cudaq::dimension_map dimensions = {{0, 2}};
Expand Down Expand Up @@ -100,7 +99,7 @@ int main() {
auto get_expectation = [](int idx, auto &result) -> std::vector<double> {
std::vector<double> expectations;

auto all_exps = result.get_expectation_values().value();
auto all_exps = result.expectation_values.value();
for (auto exp_vals : all_exps) {
expectations.push_back(exp_vals[idx].expectation());
}
Expand Down
2 changes: 1 addition & 1 deletion docs/sphinx/examples/cpp/dynamics/qubit_dynamics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ int main() {
auto get_expectation = [](int idx, auto &result) -> std::vector<double> {
std::vector<double> expectations;

auto all_exps = result.get_expectation_values().value();
auto all_exps = result.expectation_values.value();
for (auto exp_vals : all_exps) {
expectations.push_back((double)exp_vals[idx]);
}
Expand Down
8 changes: 3 additions & 5 deletions python/runtime/common/py_EvolveResult.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,17 +42,15 @@ void bindEvolveResult(py::module &mod) {
"detail.\n")
.def(
"intermediate_states",
[](evolve_result &self) { return self.get_intermediate_states(); },
[](evolve_result &self) { return self.intermediate_states; },
"Stores all intermediate states, meaning the state after each step "
"in a defined schedule, produced by a call to :func:`evolve`, "
"including the final state. This property is only populated if "
"saving intermediate results was requested in the call to "
":func:`evolve`.\n")
.def(
"final_expectation_values",
[](evolve_result &self) {
return self.get_final_expectation_values();
},
[](evolve_result &self) { return self.final_expectation_values; },
"Stores the final expectation values, that is the results produced "
"by "
"calls to :func:`observe`, triggered by a call to :func:`evolve`. "
Expand All @@ -63,7 +61,7 @@ void bindEvolveResult(py::module &mod) {
"call.\n")
.def(
"expectation_values",
[](evolve_result &self) { return self.get_expectation_values(); },
[](evolve_result &self) { return self.expectation_values; },
"Stores the expectation values, that is the results from the calls "
"to "
":func:`observe`, at each step in the schedule produced by a call to "
Expand Down
29 changes: 5 additions & 24 deletions runtime/common/EvolveResult.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,19 @@ class evolve_result {
// The final state after the time evolution.
state final_state;

public:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we match the spec here? Basically remove the intermediate / final distinction for state and expectation values and initialize everything to std::nullopt.
https://gitlab-master.nvidia.com/cuda-quantum/cudaq-spec/-/merge_requests/20/diffs

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a QQ. Does this mean cleaning up Python version as well?
https://github.com/NVIDIA/cuda-quantum/blob/main/python/runtime/common/py_EvolveResult.cpp#L43

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will have to change the Python dynamics version as well? Seems like right now evolve is kind of dependent on evolve_internal.

Can we make this change in the next release?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should be able to keep the Python API as is, juggling the binding methods. If it's more work than that, I agree, we shouldn't do it now.

This changes the public-facing api for evolve, so it's harder to change in next release.

// The state after each step in the evolution, if computed.
std::optional<std::vector<state>> intermediate_states = {};
std::optional<std::vector<state>> intermediate_states;

// The computed expectation values at the end of the evolution.
std::optional<std::vector<observe_result>> final_expectation_values = {};
std::optional<std::vector<observe_result>> final_expectation_values;

// The computed expectation values for each step of the evolution.
std::optional<std::vector<std::vector<observe_result>>> expectation_values =
{};
std::optional<std::vector<std::vector<observe_result>>> expectation_values;

// The result of sampling of an analog Hamiltonian simulation on a QPU
std::optional<sample_result> sampling_result = {};
std::optional<sample_result> sampling_result;

public:
evolve_result(state state) : final_state(state) {}

evolve_result(state state, const std::vector<observe_result> &expectations)
Expand Down Expand Up @@ -100,24 +99,6 @@ class evolve_result {
return final_state;
}

const std::optional<std::vector<state>> &get_intermediate_states() {
return intermediate_states;
}

const std::optional<std::vector<observe_result>> &
get_final_expectation_values() {
return final_expectation_values;
}

const std::optional<std::vector<std::vector<observe_result>>> &
get_expectation_values() {
return expectation_values;
}

const std::optional<sample_result> &get_sampling_result() {
return sampling_result;
}

private:
state getLastStateIfValid(const std::vector<state> &states) {
if (states.empty())
Expand Down
4 changes: 2 additions & 2 deletions runtime/cudaq/dynamics/schedule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,9 @@ void schedule::reset() {

// Get the current step
std::optional<std::complex<double>> schedule::current_step() const {
if (current_idx >= 0 && current_idx < static_cast<int>(steps.size())) {
if (current_idx >= 0 && current_idx < static_cast<int>(steps.size()))
return steps[current_idx];
}

return std::nullopt;
}

Expand Down
3 changes: 1 addition & 2 deletions runtime/nvqir/cudensitymat/CuDensityMatEvolution.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,8 @@ evolve_result evolveSingle(
cudmState->initialize_cudm(handle, dims);

state initial_State = [&]() {
if (!collapseOperators.empty() && !cudmState->is_density_matrix()) {
if (!collapseOperators.empty() && !cudmState->is_density_matrix())
return state(new CuDensityMatState(cudmState->to_density_matrix()));
}
return initialState;
}();

Expand Down
10 changes: 4 additions & 6 deletions runtime/nvqir/cudensitymat/CuDensityMatOpConverter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,8 @@ cudaq::product_operator<cudaq::matrix_operator> computeDagger(
}
std::reverse(daggerOps.begin(), daggerOps.end());

if (daggerOps.empty()) {
if (daggerOps.empty())
throw std::runtime_error("Empty product operator");
}
cudaq::product_operator<cudaq::matrix_operator> daggerProduct = daggerOps[0];
for (std::size_t i = 1; i < daggerOps.size(); ++i) {
daggerProduct *= daggerOps[i];
Expand Down Expand Up @@ -346,9 +345,9 @@ cudaq::dynamics::CuDensityMatOpConverter::createProductOperatorTerm(
int degree = sub_degrees[j];
int modality = modalities[j];

if (sub_degrees[i] < 0) {
if (sub_degrees[i] < 0)
throw std::out_of_range("Degree cannot be negative!");
}

allDegrees.emplace_back(degree);
allModeActionDuality.emplace_back(modality);
}
Expand All @@ -367,9 +366,8 @@ cudaq::dynamics::CuDensityMatOpConverter::convertToCudensitymatOperator(
const std::unordered_map<std::string, std::complex<double>> &parameters,
const operator_sum<cudaq::matrix_operator> &op,
const std::vector<int64_t> &modeExtents) {
if (op.get_terms().empty()) {
if (op.get_terms().empty())
throw std::invalid_argument("Operator sum cannot be empty.");
}

cudensitymatOperator_t cudmOperator;
HANDLE_CUDM_ERROR(cudensitymatCreateOperator(
Expand Down
40 changes: 16 additions & 24 deletions runtime/nvqir/cudensitymat/CuDensityMatState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,9 @@ CuDensityMatState::overlap(const cudaq::SimulationState &other) {
throw std::runtime_error("[CuDensityMatState] overlap error - other state "
"dimension not equal to this state dimension.");

if (other.getPrecision() != getPrecision()) {
if (other.getPrecision() != getPrecision())
throw std::runtime_error(
"[CuDensityMatState] overlap error - precision mismatch.");
}

if (!isDensityMatrix) {
Eigen::VectorXcd state(dimension);
Expand Down Expand Up @@ -112,10 +111,10 @@ CuDensityMatState::createFromSizeAndPtr(std::size_t size, void *dataPtr,
// for an invalid tensor index.
cudaq::SimulationState::Tensor
CuDensityMatState::getTensor(std::size_t tensorIdx) const {
if (tensorIdx != 0) {
if (tensorIdx != 0)
throw std::runtime_error(
"CuDensityMatState state only supports a single tensor");
}

const std::vector<std::size_t> extents =
isDensityMatrix ? std::vector<std::size_t>{dimension, dimension}
: std::vector<std::size_t>{dimension};
Expand Down Expand Up @@ -156,10 +155,10 @@ CuDensityMatState::operator()(std::size_t tensorIdx,
// Copy the state device data to the user-provided host data pointer.
void CuDensityMatState::toHost(std::complex<double> *userData,
std::size_t numElements) const {
if (numElements != dimension * (isDensityMatrix ? dimension : 1)) {
if (numElements != dimension * (isDensityMatrix ? dimension : 1))
throw std::runtime_error("Number of elements in user data does not match "
"the size of the state");
}

HANDLE_CUDA_ERROR(cudaMemcpy(userData, devicePtr,
numElements * sizeof(std::complex<double>),
cudaMemcpyDeviceToHost));
Expand Down Expand Up @@ -205,9 +204,9 @@ CuDensityMatState::CuDensityMatState(
const std::vector<int64_t> &dims)
: cudmHandle(handle), dimension(rawData.size()), cudmState(nullptr),
hilbertSpaceDims(dims) {
if (rawData.empty()) {
if (rawData.empty())
throw std::invalid_argument("Raw data cannot be empty.");
}

// Allocate device memory
size_t dataSize = rawData.size() * sizeof(std::complex<double>);
HANDLE_CUDA_ERROR(
Expand Down Expand Up @@ -255,10 +254,9 @@ CuDensityMatState::CuDensityMatState(
// Validate device memory
size_t totalSize = std::accumulate(componentBufferSizes.begin(),
componentBufferSizes.end(), 0);
if (totalSize > rawData.size() * sizeof(std::complex<double>)) {
if (totalSize > rawData.size() * sizeof(std::complex<double>))
throw std::invalid_argument(
"Device memory size is insufficient to cover all components.");
}

// Attach storage for using device memory (devicePtr)
std::vector<void *> componentBuffers(numStateComponents);
Expand Down Expand Up @@ -426,12 +424,11 @@ CuDensityMatState &
CuDensityMatState::operator=(CuDensityMatState &&other) noexcept {
if (this != &other) {
// Free existing resources
if (cudmState) {
if (cudmState)
cudensitymatDestroyState(cudmState);
}
if (devicePtr) {

if (devicePtr)
cudaFree(devicePtr);
}

// Move data from other
isDensityMatrix = other.isDensityMatrix;
Expand All @@ -456,21 +453,18 @@ CuDensityMatState::~CuDensityMatState() { destroyState(); }
bool CuDensityMatState::is_initialized() const { return cudmState != nullptr; }

bool cudaq::CuDensityMatState::is_density_matrix() const {
if (!is_initialized()) {
if (!is_initialized())
return false;
}

return dimension == calculate_density_matrix_size(hilbertSpaceDims);
}

CuDensityMatState cudaq::CuDensityMatState::to_density_matrix() const {
if (!is_initialized()) {
if (!is_initialized())
throw std::runtime_error("State is not initialized.");
}

if (is_density_matrix()) {
if (is_density_matrix())
throw std::runtime_error("State is already a density matrix.");
}

size_t vectorSize = calculate_state_vector_size(hilbertSpaceDims);
std::vector<std::complex<double>> stateVecData(vectorSize);
Expand Down Expand Up @@ -543,9 +537,8 @@ void CuDensityMatState::initialize_cudm(cudensitymatHandle_t handleToSet,

CuDensityMatState
cudaq::CuDensityMatState::operator+(const CuDensityMatState &other) const {
if (dimension != other.dimension) {
if (dimension != other.dimension)
throw std::invalid_argument("State size mismatch for addition.");
}

CuDensityMatState result = CuDensityMatState::clone(*this);

Expand All @@ -556,11 +549,10 @@ cudaq::CuDensityMatState::operator+(const CuDensityMatState &other) const {

CuDensityMatState &
cudaq::CuDensityMatState::operator+=(const CuDensityMatState &other) {
if (dimension != other.dimension) {
if (dimension != other.dimension)
throw std::invalid_argument(
fmt::format("State size mismatch for addition ({} vs {}).", dimension,
other.dimension));
}

cuDoubleComplex scalar{1.0, 0.0};
HANDLE_CUBLAS_ERROR(cublasZaxpy(
Expand Down
9 changes: 3 additions & 6 deletions runtime/nvqir/cudensitymat/CuDensityMatTimeStepper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,8 @@ CuDensityMatTimeStepper::CuDensityMatTimeStepper(
state CuDensityMatTimeStepper::compute(
const state &inputState, double t, double step_size,
const std::unordered_map<std::string, std::complex<double>> &parameters) {
if (step_size == 0.0) {
if (step_size == 0.0)
throw std::runtime_error("Step size cannot be zero.");
}

auto *simState =
cudaq::state_helper::getSimulationState(const_cast<state *>(&inputState));
Expand All @@ -34,15 +33,13 @@ state CuDensityMatTimeStepper::compute(
// Create a new state for the next step
auto next_state = CuDensityMatState::zero_like(state);

if (!next_state.is_initialized()) {
if (!next_state.is_initialized())
throw std::runtime_error("Next state failed to initialize.");
}

if (state.get_hilbert_space_dims() != next_state.get_hilbert_space_dims()) {
if (state.get_hilbert_space_dims() != next_state.get_hilbert_space_dims())
throw std::runtime_error("As the dimensions of both the old and the new "
"state do no match, the "
"operator cannot act on the states.");
}

// Prepare the operator for action
HANDLE_CUDM_ERROR(cudensitymatOperatorPrepareAction(
Expand Down
3 changes: 3 additions & 0 deletions runtime/nvqir/cudensitymat/CuDensityMatUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <vector>

namespace cudaq::dynamics {
// Adapted from cuquantum team
// GPU memory management
template <std::floating_point T>
void *createArrayGpu(const std::vector<std::complex<T>> &cpuArray) {
Expand All @@ -26,6 +27,8 @@ void *createArrayGpu(const std::vector<std::complex<T>> &cpuArray) {
}
return gpuArray;
}

// Adapted from cuquantum team
inline void destroyArrayGpu(void *gpuArray) {
if (gpuArray)
HANDLE_CUDA_ERROR(cudaFree(gpuArray));
Expand Down
Loading
Loading