Releases: QuEST-Kit/QuEST
v3.7.0
Overview
This release integrates a cuQuantum backend (generously supported by the NQCC), optimises distributed communication, and improves the unit tests.
New features
- QuEST gained a new backend which integrates cuQuantum and Thrust for optimised simulation on modern NVIDIA GPUs. This is compiled with cmake argument
-DUSE_CUQUANTUM=1
, as detailed in the compile doc. Unlike QuEST's other backends, this does require prior installation of cuQuantum, outlined here. This deployment mode should run much faster than QuEST's custom GPU backend, and will soon enable multi-GPU simulation. The entirety of QuEST's API is supported! 🎉
This work was supported by the UK National Quantum Computing centre [NQCC200921]
Other changes
- QuEST's distributed communication has been optimised when exchanging states via many maximum-size messages, thanks to the work of Jakub Adamski as per this manuscript.
- Functions like
multiQubitUnitary()
andmixMultiQubitKrausMap()
have relaxed the precision of their unitarity and CPTP checks, so they will complain less about user matrices. Now, for example, a unitarity matrixU
is deemed valid only if every element ofU*dagger(U)
has a Euclidean distance of at mostREAL_EPS
from its expected identity-matrix element. - Unit tests now check that their initial register states are as expected before testing an operator. This ensures that some tests do not accidentally pass when they should be failing (like when run with an incorrectly specified GPU compute capability) due to an unexpected all-zero initial state.
- Unit tests now use an improved and numerically stable function for generating random unitaries and Kraus maps, so should trigger fewer precision errors and false test failures.
v3.6.0
Overview
This release makes QuEST compatible with AMD GPUs 🎉, makes the unit tests compatible with MSVC on Windows, and adds sub-diagonal operators.
New features
- Compatibility with AMD GPUs, thanks to @bvillasen!
SubDiagonalOp
; a non-distributed structure representing a diagonal unitary (specified only through the diagonal elements) upon a subset of a qureg's qubits. This can be passed to new functions:createSubDiagonalOp()
destroySubDiagonalOp()
diagonalUnitary()
applySubDiagonalOp()
applyGateSubDiagonalOp()
- Functions for applying gates specified as non-unitary matrices. Specifically:
applyGateMatrixN()
applyMultiControlledGateMatrixN()
setQuregToPauliHamil()
for casting a Pauli Hamiltonian into a dense Z-basis matrix, stored in a density matrixQureg
.- Phase function
SCALED_INVERSE_SHIFTED_WEIGHTED_DISTANCE
recognised byapplyParamNamedPhaseFunc()
(and related functions)
Other changes
- Unit tests are now compatible with MSVC on Windows, and are automatically ran from Github Actions.
- Documentation is automatically regenerated whenever the master branch is updated.
Bug fixes
- Math functions used internally (like
cos()
) now explicitly use quad precision when compiled withPRECISION=4
, thanks to @Milos9304 - Fixed overflow and other precision issues in the unit tests, thanks to @rrmeister
v3.5.0
Overview
This release adds some quality-of-life functions, mostly to the benefit of larger software stacks which integrate QuEST. It also includes some bug patches and internal software architectural clean-ups, primarily by @rrmeister.
New features
setDensityAmps()
allowing direct modification of the amplitudes of a density matrix.copySubstateToGPU()
allowing partial overwriting of a statevector in GPU memorycopySubstateFromGPU()
allowing partial loading of a GPU statevector into accessible memorymixNonTPKrausMap()
to simulate Kraus maps which are not necessarily trace-preserving
Other changes
- Updated the Bernstein-Vazirani demo to simulate more analogously to the experimental method
- Updated demo codes to use precision-agnostic string formatters
- Improved CMake build (f8747ca)
- Improved the internal validation architecture
Bug fixes
- patched rare distributed bug in
calcTotalProb()
of density matrices (#326) - patched rare GPU build bug in
applyPhaseFunc()
- patched rare memory leak during failed validation of
Qureg
andDiagonalOp
validation - patched GPU build flags (512966a)
- patched
invalidQuESTInputError()
build problem on Windows (#314) - patched build warnings related to precision of internal non-simulation functions (fc25c34)
v3.4.1
Overview
This is a quick patch of a GPU build bug, and a logical error in an unimportant GPU edge-case.
Bug fixes
- patched CUDA build of v3.4.0.
- patched edge-case of
calcProbOfOutcome
which on GPU with a state-vector of a single qubit, always returned 1.
v3.4.0
Overview
This release refactors QuEST for native Windows support, and adds some initialisation and seeding utilities mostly useful for simulators which use QuEST as a backend.
New features
Deterministically project a qubit into a classical outcome without renormalising the state.
applyProjector()
Density matrices, like state-vectors, can now be directly initialised from arrays of all amplitudes.
initStateFromAmps()
Users can now view and keep track of the seeds to QuEST's random number generator.
getQuESTSeeds()
Native Windows support! QuEST can now be compiled directly in MSVC, without needing to use MinGW. An MSVC build test is now part of the Github CI, although unit tests do not yet run automatically.
- compile with CMake and NMake in the
build
folder viacmake .. -G "NMake Makefiles" nmake
- or, compile directly with GNUMake from the root directory via
cp examples/makefile . make COMPILER=cc COMPILER_TYPE=MSVC
API breaking changes
seedQuEST()
andseedQuESTDefault()
now require a pointer to the activeQuESTEnv
instance.- Previously,
SCALED_INVERSE_SHIFTED_DISTANCE
inapplyNamedPhaseFunc()
computedcoeff/sqrt( (x2-x1-dx)^2 + ... )
, but now computescoeff/sqrt( (x1-x2-dx)^2 + ...
(x1
andx2
have swapped), to be more in-line with the expected behaviour. - Previously,
SCALED_INVERSE_SHIFTED_NORM
andSCALED_INVERSE_SHIFTED_DISTANCE
inapplyNamedPhaseFunc()
used their divergence parameter when their denominators were precisely zero. Now, the divergence parameter is used whenever the denominator is withinREAL_EPS
to zero. This catches the scenario when a divergence has been translated only a very small distance from a sampled point.
v3.3.0
Overview
This release adds some powerful new operators including pauli gadgets with any number of control qubits, diagonal operators expressed as general exponential-polynomial phase functions, and optimised implementations of the quantum Fourier transform and multi-controlled multi-target X gates. It brings the ability to efficiently calculate batches of probabilities of arbitrary quantum substates, and functions for creating diagonal operators from Ising Hamiltonians. These utilities are useful for high-performance simulation of quantum chemistry algorithms. Finally, we add an example implementation of Grover's algorithm, and the documentation is given a welcome face-lift.
New features
In addition to calcProbOfOutcome
for calculating the probability of a single qubit outcome, one can now efficiently obtain the entire set of probabilities for the classical outcomes of entire sub-registers.
calcProbOfAllOutcomes()
Added optimised algorithmic methods for simultaneously applying multiple Pauli X gates. These run as fast as a single invocation of pauliX()
, even in distributed mode!
multiQubitNot()
multiControlledMultiQubitNot()
.
With the help of Milos Prokop, Ising Hamiltonians expressed in the Pauli basis can now be loaded directly into diagonal operators, for much faster simulation.
initDiagonalOpFromPauliHamil()
createDiagonalOpFromPauliHamilFile()
Added controlled versions of the existing phase gadgets and Pauli gadgets.
multiControlledMultiRotateZ()
multiControlledMultiRotatePauli()
Added an efficient implementation of the quantum Fourier transform (QFT), which can be applied to both state-vectors and density-matrices, on an arbitrary sub-register.
applyQFT()
applyFullQFT()
With the help of Richard Meister, diagonal unitaries can be applied directly to a state, specified as a phase function, and requiring no dedicated memory. This includes phase functions specified as one-dimensional exponential-polynomials...
applyPhaseFunc()
applyPhaseFuncOverrides()
or as multi-variable exponential-polynomials...
applyMultiVarPhaseFunc()
applyMultiVarPhaseFuncOverrides()
or as one of many named phase functions, including several useful for quantum chemistry simulations, like measures of distance between registers representing signed integers in two's complement!
applyNamedPhaseFunc()
applyNamedPhaseFuncOverrides()
applyParamNamedPhaseFunc()
applyParamNamedPhaseFuncOverrides()
Finally, some changes to documentation.
- updated the tutorial (
examples/README.md
) with extensive compilation and testing guidance - added example implementation of Grover's search
createQureg
andcreateDensityQureg
now include extensive documentation about their memory patterns on all hardware backends- added doc for
QuEST_PREC
,ComplexMatrix2
andComplexMatrix4
- added 'see more' sections to most functions, linking to related functions
- linked all doc to
invalidQuESTInputError()
, if thrown - function exceptions are now formatted cleanly in lists
- code snippets now use syntax highlighting
- removed ugly borders around circuit diagrams
Bug fixes
- patched
syncDiagonalOp
which previously did not copy all of a state-vector into GPU memory - supressed CMake build warnings (by Gleb Struchalin)
- fixed doc rendering issue (via regrettable js/html hacks)
- fixed all doxygen warnings
- patched unit tests to compile precision agnostically
- patched QASM output to compile precision agnostically
- patched distributed file IO unit tests (like
createPauliHamilFromFile
), which sometimes seg-faulted
v3.2.1
Overview
A minor patch to the QuEST build.
Changes
getEnvironmentString()
now returns a standard format between the serial, multithreaded, distributed, and GPU-accelerated backends. This enables convenient parsing by interfacing projects, like pyQuEST.
Bug fixes
- removed unnecessary check for OpenMP compilers in non-multithreaded mode (by external contributor, Christopher Andrews @chr5tphr)
v3.2.0
Overview
This release adds a new encapsulation for representing Hamiltonians in the Pauli basis, adds efficient representation of diagonal operators, adds continuous time simulation through Trotter-Suzuki decompositions, and enables multiplying arbitrary complex matrices directly onto quantum states.
New features
Added a new type, PauliHamil
, representing a weighted sum of Pauli strings; a common basis for representing Hamiltonians.
createPauliHamil()
createPauliHamilFromFile()
initPauliHamil()
destroyPauliHamil()
reportPauliHamil()
applyPauliHamil()
calcExpecPauliHamil()
Added the ability to generate Trotter circuits, including higher order 'symmetrized' Suzuki decompositions. This can be used to unitarily evolve a state in time, under a given PauliHamil
. The gates prescribed by the decomposition can be captured with QASM logging.
applyTrotterCircuit()
Added a new type, DiagonalOp
, which can represent non-unitary and even non-Hermitian diagonal operators acting on the full Hilbert space. The data for this operator is distributed, and persists in GPU memory, for rapid simulation.
createDiagonalOp()
destroyDiagonalOp()
initDiagonalOp()
syncDiagonalOp()
applyDiagonalOp()
calcExpecDiagonalOp()
Added support for directly multiplying arbitrary complex matrices onto a state-vector or density-matrix.
applyMatrix2()
applyMatrix4()
applyMatrixN()
applyMultiControlledMatrixN()
Bug fixes
- fixed OpenMP linking on MacOS (by external contributor, Drew Silcock @drewsilcock)
- fixed CUDA compiling with CMake (by external contributor, @SachinCompton)
- fixed multithreading with gcc-9 (with help from external contributor, Zach van Rijn @zv-io)
- tweaked unit testing precision tolerances
v3.1.1
Overview
Patching a GPU memory leak, and some minor bugs in the build and validaition.
Bug fixes
- Issue #239: patched a memory leak in
destroyQureg
on GPU (Tyson Jones) - PR #230: patched bug in
createQureg
's validation, which prevented creating quregs larger than32
qubits (Kshitij Chhabra) - Issue #236: Patched cmake build so that flags (like
PRECISION
) are given also to user source (Ania Brown) - Patched tutorial warnings when
PRECISION != 2
(madeprintf
precision-agnostic) (Tyson Jones)
Acknowledgements
We thank Kshitij Chhabra for their well-spotted bug fix in createQureg
!
v3.1.0
Overview
This release introduces rigorous unit testing of the QuEST API, sets-up continuous-intergration, improves validation, and gives the documentation a face-lift. We thank Fergus Cooper for setting up QuEST's CI.
Unit tests
tests/
now contains a suite of hardware-agnostic unit tests which rigorously check every inch of the QuEST API. We compare the optimised calculations that QuEST performs, against slow, unoptimised but provably correct calculation. We check every possible, meaningfully distinct input to every QuEST function (for example, all possible arrangements of control and target qubits) gives the correct behaviour.
With these tests, we have almost absolute assurance that the QuEST API does what it says on the tin.
These tests can be run with
mkdir build && cd build
cmake .. -DTESTING=ON
make
make test
Read more about the new tests in this PR, and view the tests in the doc.
Validation
QuEST will now report if it is being initialised incorrectly. For example, trying to distribute QuEST over a non-power-of-2 number of nodes will fail gracefully, with an error message. It will also report if it cannot fit an attemptedly-created Qureg
in memory, if for example it is too large, or too small to distribute.
Doc
Finally, the documentation has been restyled.