[unitaryhack] Add closed- and open-system dynamics propagators#4672
[unitaryhack] Add closed- and open-system dynamics propagators#4672friedsam wants to merge 22 commits into
Conversation
Signed-off-by: Claudia Friedsam <claudia.friedsam@gmail.com>
Signed-off-by: Claudia Friedsam <claudia.friedsam@gmail.com>
b10a7e0 to
608c313
Compare
|
Thanks @friedsam for the contribution! Could you also please extend this PR to cover open-quantum systems (with collapse operators) as mentioned in #3437 (comment)? For example, the propagator ( would follow this ODE: |
|
Thanks, yes. I’ll extend the helper to support collapse operators and return the Lindblad superoperator propagator for open-system dynamics. |
Signed-off-by: Claudia Friedsam <claudia.friedsam@gmail.com>
Command Bot: Processing... |
|
Thanks. I extended the helper to support collapse operators and return the Lindblad superoperator propagator for open-system dynamics. The implementation follows the existing CUDA-Q Local validation:
|
|
Hi @friedsam, The test is failing: For this task, I think you'd need a machine with NVIDIA GPU to do the validation/debug. |
|
Thanks. Could you please paste the traceback for the three failing tests? I can likely patch from the failure details. I’m also looking into a temporary NVIDIA GPU environment, but the traceback would be the fastest path. |
Signed-off-by: Claudia Friedsam <claudia.friedsam@gmail.com>
Here is the log: |
CI Summary (
|
| Job | Result |
|---|---|
binaries |
⏩ skipped |
build_and_test |
✅ success |
config_devdeps |
✅ success |
config_source_build |
⏩ skipped |
config_wheeldeps |
✅ success |
devdeps |
✅ success |
docker_image |
⏩ skipped |
gen_code_coverage |
⏩ skipped |
metadata |
✅ success |
python_metapackages |
⏩ skipped |
python_wheels |
⏩ skipped |
source_build |
⏩ skipped |
wheeldeps |
✅ success |
⏩ Skipped jobs (7) — intentionally skipped on PR builds; run on merge_group / workflow_dispatch
| Job |
|---|
binaries |
config_source_build |
docker_image |
gen_code_coverage |
python_metapackages |
python_wheels |
source_build |
All sub-jobs (42) — every matrix leg, with links
| Job | Status | Link |
|---|---|---|
| Build and test (amd64, gcc12, openmpi) / Dev environment (Debug) | ✅ success | view |
| Build and test (amd64, gcc12, openmpi) / Dev environment (Python) | ✅ success | view |
| Build and test (amd64, llvm, openmpi) / Dev environment (Debug) | ✅ success | view |
| Build and test (amd64, llvm, openmpi) / Dev environment (Python) | ✅ success | view |
| Build and test (arm64, llvm, openmpi) / Dev environment (Debug) | ✅ success | view |
| Build and test (arm64, llvm, openmpi) / Dev environment (Python) | ✅ success | view |
| CI Summary | ❔ in_progress | view |
| Configure build (devdeps) | ✅ success | view |
| Configure build (source_build) | ⏩ skipped | view |
| Configure build (wheeldeps) | ✅ success | view |
| Create CUDA Quantum installer | ⏩ skipped | view |
| Create Docker images | ⏩ skipped | view |
| Create Python metapackages | ⏩ skipped | view |
| Create Python wheels | ⏩ skipped | view |
| Gen code coverage | ⏩ skipped | view |
| Load dependencies (amd64, gcc12) / Caching | ✅ success | view |
| Load dependencies (amd64, gcc12) / Finalize | ✅ success | view |
| Load dependencies (amd64, gcc12) / Metadata | ✅ success | view |
| Load dependencies (amd64, llvm) / Caching | ✅ success | view |
| Load dependencies (amd64, llvm) / Finalize | ✅ success | view |
| Load dependencies (amd64, llvm) / Metadata | ✅ success | view |
| Load dependencies (arm64, gcc12) / Caching | ✅ success | view |
| Load dependencies (arm64, gcc12) / Finalize | ✅ success | view |
| Load dependencies (arm64, gcc12) / Metadata | ✅ success | view |
| Load dependencies (arm64, llvm) / Caching | ✅ success | view |
| Load dependencies (arm64, llvm) / Finalize | ✅ success | view |
| Load dependencies (arm64, llvm) / Metadata | ✅ success | view |
| Load source build cache | ⏩ skipped | view |
| Load wheel dependencies (amd64, 12.6) / Caching | ✅ success | view |
| Load wheel dependencies (amd64, 12.6) / Finalize | ✅ success | view |
| Load wheel dependencies (amd64, 12.6) / Metadata | ✅ success | view |
| Load wheel dependencies (amd64, 13.0) / Caching | ✅ success | view |
| Load wheel dependencies (amd64, 13.0) / Finalize | ✅ success | view |
| Load wheel dependencies (amd64, 13.0) / Metadata | ✅ success | view |
| Load wheel dependencies (arm64, 12.6) / Caching | ✅ success | view |
| Load wheel dependencies (arm64, 12.6) / Finalize | ✅ success | view |
| Load wheel dependencies (arm64, 12.6) / Metadata | ✅ success | view |
| Load wheel dependencies (arm64, 13.0) / Caching | ✅ success | view |
| Load wheel dependencies (arm64, 13.0) / Finalize | ✅ success | view |
| Load wheel dependencies (arm64, 13.0) / Metadata | ✅ success | view |
| Prepare cache clean-up | ❔ in_progress | view |
| Retrieve PR info | ✅ success | view |
✅ Required checks (6/6) — declared in .github/required-checks.yml for push
| Required check | Status | Link |
|---|---|---|
| Build and test (amd64, llvm, openmpi) / Dev environment (Debug) | ✅ success | view |
| Build and test (amd64, llvm, openmpi) / Dev environment (Python) | ✅ success | view |
| Build and test (arm64, llvm, openmpi) / Dev environment (Debug) | ✅ success | view |
| Build and test (arm64, llvm, openmpi) / Dev environment (Python) | ✅ success | view |
| Build and test (amd64, gcc12, openmpi) / Dev environment (Debug) | ✅ success | view |
| Build and test (amd64, gcc12, openmpi) / Dev environment (Python) | ✅ success | view |
Signed-off-by: Claudia Friedsam <claudia.friedsam@gmail.com>
Signed-off-by: Claudia Friedsam <claudia.friedsam@gmail.com>
Signed-off-by: Claudia Friedsam <claudia.friedsam@gmail.com>
|
Thanks, that makes sense. I see the distinction: the current open-system branch constructs the Lindblad RHS for density-matrix evolution, while the requested object is the propagator I’ll revise the open-system implementation to construct the Liouvillian on |
|
Thanks — I think the API-compatible way to implement the open-system propagator is to assemble
This should give the requested map Does that match what you had in mind? |
Signed-off-by: Claudia Friedsam <claudia.friedsam@gmail.com>
|
Updated. The open-system branch now assembles the propagator map by evolving the Liouville-space basis vectors under the Lindblad Local checks pass. The pytest module remains GPU-gated and skips locally. |
|
You are very correct with this. I’ll switch this from a Python-side serial loop to a batched |
I posted a comment in the code. I think this is not an efficient way to use the GPU as we made the computation sequential. For testing coverage, we can test normal density matrix state evolve and a propagator calculation based on the same dynamics. The final density matrix |
Thanks! Please let us know when you get a chance to actually validate all the tests so that we can take a closer look at the implementation. |
Signed-off-by: Claudia Friedsam <claudia.friedsam@gmail.com>
|
Updated and GPU-tested. I changed the open-system implementation to construct the dense Liouvillian I also ran the contrib propagator tests on a Brev NVIDIA L40S GPU instance: ===================================================== test session starts ====================================================== python/tests/contrib/test_propagator.py::test_propagator_constant_z_hamiltonian PASSED [ 12%] ====================================================== 8 passed in 1.42s ======================================================= |
Signed-off-by: Claudia Friedsam <claudia.friedsam@gmail.com>
Signed-off-by: Claudia Friedsam <claudia.friedsam@gmail.com>
|
Updated to preserve the structured This now builds the Lindblad generator using GPU-tested on Brev NVIDIA L40S: python -m pytest python/tests/contrib/test_propagator.py -q -vv -rs 8 passed in 1.45s |
Signed-off-by: Claudia Friedsam <claudia.friedsam@gmail.com>
Signed-off-by: Claudia Friedsam <claudia.friedsam@gmail.com>
Command Bot: Processing... |
|
Hi @friedsam, Just checking in on this PR. Thanks again for opening it; this is a nice contribution, and it looks very close. The remaining feedback is minor, mostly around code comments/test coverage. Really appreciate your contribution to CUDA-Q! |
|
Hi, thank you so much for all the feedback. I actually worked on it last evening but didn't push as I didn't want to disrupt the tests. I will finish it up tonight, test on brev again and commit everything |
Signed-off-by: Claudia Friedsam <claudia.friedsam@gmail.com>
Signed-off-by: Claudia Friedsam <claudia.friedsam@gmail.com>
|
Updated the batched open-system path to flatten the Hamiltonian/basis-state combinations before calling I also added the requested helper comments and tests for nonzero Hamiltonian plus collapse operators, shared collapse operators across Hamiltonian batches, and per-Hamiltonian collapse-operator lists. GPU-tested on Brev NVIDIA L40S: (cudaq-test) ubuntu@crusoe-prod--inst-3evbehfhoujpidcjh56yh7x5y5i:~/cuda-quantum$ python -m py_compile python/cudaq/contrib/propagator.py python/tests/contrib/test_propagator.py python/tests/contrib/test_propagator.py::test_propagator_constant_z_hamiltonian PASSED [ 7%] ====================================================== 13 passed in 1.75s ====================================================== |
Command Bot: Processing... |
|
Re: https://github.com/NVIDIA/cuda-quantum/actions/runs/27244073636/job/80455376958?pr=4672 We can use backsticks (`) to escape those specialized terms in the Python code comments. |
Signed-off-by: Claudia Friedsam <claudia.friedsam@gmail.com>
Signed-off-by: Claudia Friedsam <claudia.friedsam@gmail.com>
Command Bot: Processing... |
Signed-off-by: Claudia Friedsam <claudia.friedsam@gmail.com>
Command Bot: Processing... |
Command Bot: Processing... |
Closes #3437.
Adds
cudaq.contrib.propagatorfor closed- and open-system dynamics.For closed-system dynamics, the helper computes the propagator
U(t)satisfyingdU/dt = -i H(t) U, U(t_initial) = I
by evolving the identity matrix under the left-multiplication superoperator generated by
-i H(t).For open-system dynamics with collapse operators, the helper computes the Lindblad superoperator propagator
S(t)satisfyingd vec(rho)/dt = L(t) vec(rho), S(t_initial) = I
by evolving the Liouville basis states through
cudaq.evolvewith the supplied collapse operators and stacking the evolved basis states into the dense propagator matrix.Implementation:
cudaq.contrib.propagatorcudaq.SuperOperator.left_multiply(-1j * H)cudaq.evolvecudaq.evolve(dim, dim)for closed-system propagators(dim**2, dim**2)for open-system Lindblad propagatorsTests:
ZHamiltonian vsscipy.linalg.expmXHamiltonian vsscipy.linalg.expmscipy.integrate.solve_ivpscipy.linalg.expmof the Lindblad generatorLocal validation:
python -m yapf -i python/cudaq/contrib/propagator.pypython -m py_compile python/cudaq/contrib/propagator.py python/tests/contrib/test_propagator.pypython -m pytest python/tests/contrib/test_propagator.py -q -rspython -m pre_commit run spellcheck --all-files --hook-stage pre-pushpython -m pre_commit run --files python/cudaq/contrib/propagator.pygit diff --checkGPU validation:
python -m pytest python/tests/contrib/test_propagator.py -q -vv -rs14 passed in 2.38sAI assistance disclosure:
I used AI to help reason through the CUDA-Q dynamics API and to help with drafting/debugging for the initial implementation and tests. The numerical tests are GPU-gated and were skipped locally because no NVIDIA GPU/dynamics backend is available on my machine.