Skip to content

Conversation

@mcjamieson
Copy link

Summary

Added comprehensive input validation tests for quantum measurement and time evolution operations.

Changes

operations.cpp

  • Added 12 validation test sections covering measurement, projection, and PauliStrSum operations
  • Tests verify proper error handling for invalid quantum registers, out-of-bounds qubits, duplicate targets, and zero targets

trotterisation.cpp

  • Added complete test suite for unitary and imaginary time evolution operations
  • Includes 8 validation sections testing invalid inputs (bad registers, non-Hermitian Hamiltonians, invalid Trotter parameters)
  • Added 4 correctness test scenarios for imaginary time evolution: strong magnetic field, opposite magnetic field, ferromagnetic system, and antiferromagnetic system. Each verifies the algorithm converges to the expected lowest-energy configuration.

Test Results

  • All 12 operations validation tests pass
  • applyTrotterizedUnitaryTimeEvolution: 19 assertions
  • applyTrotterizedImaginaryTimeEvolution: 262,153 assertions

TysonRayJones and others added 4 commits May 28, 2025 03:06
Updates version references and fixes doxygen parsing of CMake configured header broken in QuEST-Kit#616
@mcjamieson mcjamieson marked this pull request as draft January 14, 2026 16:47
@mcjamieson mcjamieson marked this pull request as ready for review January 14, 2026 16:47
@otbrown otbrown self-assigned this Jan 14, 2026
@otbrown
Copy link
Collaborator

otbrown commented Jan 14, 2026

Thanks Maurice! I'll add reviewing this to my list.

@otbrown otbrown changed the base branch from main to devel January 14, 2026 17:33
@tom-quantummotion
Copy link

Thanks @mcjamieson!

@otbrown
Copy link
Collaborator

otbrown commented Jan 15, 2026

There is a PR to the PR which fixes conflicts arising from Vasco's concurrent changes to the time evolution API!

@otbrown
Copy link
Collaborator

otbrown commented Jan 16, 2026

Looks like I should take a closer look at the validation tests! I'll schedule it for Monday.

@otbrown
Copy link
Collaborator

otbrown commented Jan 19, 2026

Okay the single precision tests are failing because of the validate_expecPauliStrSumValueIsReal validation check in calcExpecPauliStrSum. The check fails with:

Expectation value: 19.2772 + i0.00159493
Epsilon: 0.001

Epsilon is already uprated from the single precision default value of 1E-5 by the REDUCTION_EPSILON_FACTOR for reduction operations -- that value is somewhat arbitrarily set.

For comparison the equivalent values at double precision are:

Expectation value: 19.2683 + i7.30146e-14
Epsilon: 1e-10

Note that the real component is also not within tolerance -- I suspect that the exponential calculation is responsible for the drift at single precision.

Arguably it doesn't make sense to be doing time evolution at single precision, but that would be a documentation issue. For the time being I'll adjust the tests to have much lower expectations of the accuracy of this result at single precision.

@otbrown
Copy link
Collaborator

otbrown commented Jan 19, 2026

Note that there is also a difference between the results for serial and multithreaded versions of the time evolution, probably down to the underlying numerical method used in either case.

Double precision:
  OMP_NUM_THREADS=8 (baseline):
    Expectation value: 19.2683 + i-2.49685e-16
  OMP_NUM_THREADS=1:
    Expectation value: 19.2683 + i7.30146e-14
Single precision:
  OMP_NUM_THREADS=8:
    Expectation value: 19.2689 + i2.60701e-05
  OMP_NUM_THREADS=1
    Expectation value: 19.2772 + i0.00159493

So epsilon needs to create quite a wide window...

…n to account for worst-case scenario which is single precision, single thread
@TysonRayJones
Copy link
Member

TysonRayJones commented Jan 19, 2026

Ooh the improved multithreaded accuracy is a nice demonstration of the benefit of heirarchal reductions 🎉 Changing epsilon for the tests is fine; it can even be done for that particular function only by using getValidationEpsilon() and restoring it at the end of the test case.

There are some minor issues with the tests, such as use of createQureg() which will break distribution above a certain number of nodes, rather than using prior created cached quregs. And some missing validations. Quicker for me to address these in a direct commit to this PR which I'll do presently

EDIT woops, createQureg is actually always safe because the auto-deployer will simply disable distribution when the Qureg is too small. But alas, it's nice to centralise/avoid temporary Qureg allocs and avoid the risks/noise of memory leaks when tests fail.

[ ] note to self: update "untested" warnings in doc

since it will be used frequently by new input validation
so that test failures do not cause memory leaks and e.g. add to valgrind noise. Tests now instead use getArbitraryCachedStatevec() or getArbitraryCachedDensmatr() to obtain an existing qureg with an arbitrary deployment.
since the validation for these functions wasn't added. Such functions have additional tests to their tested counterparts; for example, validating that matrix elements are non-zero when given a negative exponent
and adding a missing Hermiticity validation to applyTrotterizedUnitaryTimeEvolution test
Previously, an error message of the C++ API was not substituting in values for its placeholder variables. This affected the C++ variants of the below functions when passing vectors for the targets and outcome parameters of mismatching length:
- calcProbOfMultiQubitOutcome
- leftapplyMultiQubitProjector
- rightapplyMultiQubitProjector
- applyMultiQubitProjector
- applyForcedMultiQubitMeasurement
@otbrown
Copy link
Collaborator

otbrown commented Jan 20, 2026

Thanks for the patches Tyson!

Yes indeed, I've submitted a PR to Maurice's PR which uses that interface to set tolerances which will work for this set of tests, even on single-threaded single-precision runs. Should be able to get this merged once that's merged.

Overall, I think the lesson probably is "don't try to time evolve a quantum state at single-precision", although I think there probably are ways this could be improved At Some Point™️.

@otbrown
Copy link
Collaborator

otbrown commented Jan 21, 2026

All checks passed 🎊

There are certainly several improvements to be made, including using cached quregs (which I think should certainly be possible for the imaginary time evolutions), as well as a few options I can think of for dealing with the difference across precisions.

Rather than let perfect be the enemy of good however, my preference would be to merge this so we have some testing and then open a new issue to track improvements. Barring any objections I'll do that tomorrow evening!

@otbrown otbrown merged commit 62ac321 into QuEST-Kit:devel Jan 22, 2026
130 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants