[fix] Repair Dynamiqs backend resolve and add QuTiP parity tests#52
Open
Ronit-Raj9 wants to merge 1 commit into
Open
[fix] Repair Dynamiqs backend resolve and add QuTiP parity tests#52Ronit-Raj9 wants to merge 1 commit into
Ronit-Raj9 wants to merge 1 commit into
Conversation
The Dynamiqs backend crashed inside dq.sesolve: it passed a solver= kwarg and dq.solver.Tsit5(), neither of which exists in dynamiqs 0.3.2. It now calls sesolve with method=dq.method.Tsit5 and an explicit dq.Options. Changes: - Add DynamiqsSolverOptions with explicit Tsit5 defaults (rtol=atol=1e-8) and the progress meter off by default, which also avoids the Jupyter ZMQError from issue OpenQuantumDesign#26. - Build the sesolve save times host-side from the float duration and timestep, so no traced value is branched on and the solve stays jit-able. - Add TaskArgsAtomicEmulator (a TaskArgsAtomic subclass) and run_task so solver options can flow through a Task, mirroring the analog emulator's QutipBackend. - Drop the duplicate Hilbert-space analysis pass and raise a real ValueError instead of a bare string. - Fix the empty-gate timeline double-offset and the initial_state check in both the Dynamiqs and QuTiP VMs. - Document the rad/s and seconds unit convention in code and in the docs. Tests cover QuTiP vs Dynamiqs parity on the microwave Rabi and red-sideband circuits (they agree to ~1e-8), the lowered Hamiltonian at gate times, jit and gradient compatibility, the solver options, and run_task. Fixes OpenQuantumDesign#43
4 tasks
Member
|
Going to accept this for the unitaryHACK bounty. The QuTiP parity at ~1e-8 is good, and I appreciate the explicit tests for end-to-end |
1 task
Author
|
Thanks for accepting this @benjimaclellan.. Do let me know if i could do any changes or something... I liked working with this... Probably want to contribute after unitaryHack too.. |
Member
|
Thanks @Ronit-Raj9, that sounds great. We have a few changes/PRs to merge from the unitaryHACK and other work, so I'm going to leave this PR open as-is, and we'll keep in touch if there's some tweaks that would be useful here or other contributions to the repo. |
Author
|
Sure @benjimaclellan |
This file contains hidden or 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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
● Fixes the Dynamiqs backend so it actually runs and matches QuTiP. The old code called dq.sesolve with solver=dq.solver.Tsit5(), but that kwarg and the dq.solver namespace don't exist in dynamiqs 0.3.2, so it just crashed. Switched to method=dq.method.Tsit5 with explicit dq.Options.
Changes:
Fixes #43
Mostly a bug fix, plus a small Task-based entry point and a docs update.
The backend crashes on any real run (#43) because of the bad sesolve call, and throws a ZMQError in Jupyter from the progress meter (#26). The existing tests only build the VMs, they never run a solve, so nothing was actually verified.
It runs end to end and matches QuTiP to ~1e-8 on the Rabi carrier and red-sideband cases. Solver and tolerances are explicit and overridable (on the backend or via a Task), the progress meter is off by default, and the units are documented. Added parity, Hamiltonian-at-gate-time, jit and gradient tests.
No. The only change is the solver_options default going from {} to None (None just falls back to the defaults). The old {} couldn't run anyway, and passing a dict still works.
run_task and TaskArgsAtomicEmulator are additive, so compile/run are untouched and still mirror QutipBackend. TaskArgsAtomicEmulator subclasses oqd-core's TaskArgsAtomic so a normal Task validates it (no model_construct). map_OperatorMul is left as-is, the 1e-8 parity confirms it's already correct. ruff, copyright, pytest (13 passed, 2 xfailed) and mkdocs all pass locally.