Skip to content

Releases: QuEST-Kit/QuEST

v4.1.0

28 May 02:19
2d1a6fb
Compare
Choose a tag to compare

Overview

This minor release (#622) adds some convenience functions to control QuEST's reporter functions, patches a critical segmentation fault in simulation above 32 qubits, patches the build's installation process and some minor reporter issues, and improves the documentation.

New features

Two new Debug > Reporting functions customise the outputs of functions like reportPauliStr() and reportPauliStrSum():

Patches

  • #623 patched a critical bug in the amplitude-enumeration logic which caused a segmentation fault for simulations of over 32 qubits (believed to cause #618).
  • 15a08ae removed superfluous re-validation of user input inside Trotter circuits.
  • 5e449fe patched a seg-fault when calling setMaxNumReportedItems(1,1) (though insignificant bug #588 remains).
  • fb2527e patched reportScalar() which previously ignored the number of sig-figs set with setMaxNumReportedSigFigs().
  • c92ebb3 patched invalid-input error messages that interrupt reports which do not end in a trailing newline (by now always printing a newline before the error message).
  • #624 restored C++17 compatibility of the source (by removing non-standard designated initialisers), which is now targeted by the build (though unit tests still require C++20).
  • #601 and #616 patched the build's install process which previously required users to gratuitously re-specify preprocessor macros (like COMPILE_MPI) when including the pre-installed QuEST header.
  • 420e11d ensures that changes to the devel branch will trigger CI tests (as intended).

Other changes

  • Examples have been restructured, and a new example using QuEST to perform real-time Hamiltonian simulation (dynamics.c(pp)) was added.
  • CI now runs Windows tests first since they are the most error-prone.
  • CI now runs all isolated examples (in addition to merely compiling them), testing for link-time issues (see e9fa519).
  • CI now compiles and runs all files in the new automated examples folder, offering external contributors a quick and easy way to platform-agnostically test their PR (in lieu of preparing a unit test)(see e9fa519).
  • Code-coverage reporting in PRs (using LCOV) was disabled since it did not capture accelerated backend coverage.
  • Many functions received new documentation (although the war continues).
  • Several custom Doxygen tags were renamed (see #621)

New contributors

This release contained patches from new contributors:

v4.0.0

06 Apr 23:25
53f8f3a
Compare
Choose a tag to compare

🎉  What's new

QuEST v4 has completely overhauled the API, software architecture, algorithms, implementations and testing. This page details the new features, divided into those relevant to users, developers who integrate QuEST into larger software stacks, and contributors who develop QuEST or otherwise peep at the source code!

TOC:

For users

  • auto-deployer
    Functions like createQureg() and createFullStateDiagMatr() will automatiaclly decide whether to make use of the compiled and available hardware facilities, like multithreading, GPU-acceleration and distribution. The user no longer needs to consider which deployments are optimal for their simulation sizes, nor which devices have sufficient memory to fit their Qureg!

  • new deployments
    QuEST can now make use of multiple GPUs, distributed across different machines on a network, or tightly-coupled by a high-bandwidth interconnect (like NVLink); or both! This is true independent of whether you're also using cuQuantum, NVIDIA or AMD GPUs. Further, used deployments are heterogeneous; simultaneous Quregs may use different facilities at runtime!

  • much faster
    Practically all backend algorithms have been replaced with novel, optimised, bespoke routines - primarily documented in arXiv 2311.0512. Further, special care has been paid to enabling compile-time optimisations, giving structures (like matrices) persistent GPU memory, and lazily evaluating properties like matrix unitarity only once!

  • cleaner interface
    The API has been polished; function names are more consistent, accept an arithmetic-overloaded complex scalar type (called qcomp), and more natural data structures. Matrices, Pauli tensors and their weighted sums are now easier to initialise and populate, accepting even matrix and string literals!
    Some functions now have type overloads - even the C ones! - and additional C++ overloads accepting native containers like std::vector.

  • reporters
    The API also includes utilities for prettily printing all QuEST data structures (like states, operators and scalars) and reporting on the environment and Qureg hardware accelerations being used, the memory available, and the maximum possible simulation sizes.
    Input validation has also been massively broadened and error messages made precise and dynamic. Usability is through the roof!

  • new functions
    The set of supported quantum operations has greatly expanded. All unitaries can be effected with any number of control qubits (in any state), diagonal matrices can be raised to powers, density matrices can undergo partial tracing and inhomogeneous Pauli channels (in addition to general Kraus maps and superoperatos), and multi-qubit projectors can now be performed, with and without renormalisation.

  • more control
    Extensive new debugging facilities allow disabling or changing the validation precision and error response at runtime, and controlling how many amplitudes and significant figures of Qureg and matrices are printed.

  • better documentation
    The documentation has been rewritten from the ground-up, and the API doc grouped into sub-categories and aesthetically overhauled with Doxygen Awesome. It is now more consistently structured, mathematically explicit, and is a treat on the eyes!

For developers

  • new build
    The CMake build has been overhauled and modernised, with wider platform support and facilities to ease QuEST's integration into larger stacks. The build is more modular, limiting specialised compilers (like nvcc and mpicc) to compiling only their essential files. This minimises friction and widens QuEST's compiler support.

  • easier integration
    QuEST's backend now uses the standard C++ complex primitive to represent quantum amplitudes and matrix elements, made precision agnostic via new qcomp type. Further, dense matrices now have both 1D row-major and 2D (aliasing the 1D) memory pointers. This permits Qureg and matrix data to be seamlessly accessed by third-party libraries, such as for linear algebra, without the need for adapters nor expensive copying.

For contributors

  • modular architecture
    QuEST's new software architecture is highly modular, separating the responsibilities of interfacing, validating user input, core pre-processing, localising distributed data, choosing which accelerator to use (CPUs or GPUs), and modifying local data using an accelerator. The core pre-processing is further modularised into modules responsible for autodeploying, inlining, performing maths and bitwise routines, probing available memory, checking internal preconditions, parsing user text, printing output, managing data structures and generating random numbers.
    See architecture.md for more information.

  • C++ backend
    While QuEST's frontend remains C and C++ agnostic, the backend has become consistently C++17, affording development luxuries like overloading, templating, type inference, namespaces, smart pointers, constant expressions, type-traiting, structured bindings, range-based looping and use of standard lists like vector. We have however endeavoured to keep the use of C++ facilities simple so that the code remains readable and editable by C programmers.

  • internal preconditions
    QuEST's defensive design has massively improved by the extensive use of precondition checks, which cheaply validate that internal functions receive correct inputs, where there is room for insidious bugs or future changes.
    This...

Read more

v3.7.0

22 Sep 11:17
d4f75f7
Compare
Choose a tag to compare

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() and mixMultiQubitKrausMap() have relaxed the precision of their unitarity and CPTP checks, so they will complain less about user matrices. Now, for example, a unitarity matrix U is deemed valid only if every element of U*dagger(U) has a Euclidean distance of at most REAL_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

07 Aug 18:01
eac4409
Compare
Choose a tag to compare

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 matrix Qureg.
  • Phase function SCALED_INVERSE_SHIFTED_WEIGHTED_DISTANCE recognised by applyParamNamedPhaseFunc() (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 with PRECISION=4, thanks to @Milos9304
  • Fixed overflow and other precision issues in the unit tests, thanks to @rrmeister

v3.5.0

21 Apr 10:07
23a0a08
Compare
Choose a tag to compare

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 memory
  • copySubstateFromGPU() allowing partial loading of a GPU statevector into accessible memory
  • mixNonTPKrausMap() 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 and DiagonalOp 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

13 Oct 12:16
9494994
Compare
Choose a tag to compare

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

10 Oct 07:23
Compare
Choose a tag to compare

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 via
    cmake .. -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() and seedQuESTDefault() now require a pointer to the active QuESTEnv instance.
  • Previously, SCALED_INVERSE_SHIFTED_DISTANCE in applyNamedPhaseFunc() computed coeff/sqrt( (x2-x1-dx)^2 + ... ), but now computes coeff/sqrt( (x1-x2-dx)^2 + ... (x1 and x2 have swapped), to be more in-line with the expected behaviour.
  • Previously, SCALED_INVERSE_SHIFTED_NORM and SCALED_INVERSE_SHIFTED_DISTANCE in applyNamedPhaseFunc() used their divergence parameter when their denominators were precisely zero. Now, the divergence parameter is used whenever the denominator is within REAL_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

22 Aug 13:14
Compare
Choose a tag to compare

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 and createDensityQureg now include extensive documentation about their memory patterns on all hardware backends
  • added doc for QuEST_PREC, ComplexMatrix2 and ComplexMatrix4
  • 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

06 Jun 17:30
Compare
Choose a tag to compare

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

21 Jul 20:46
Compare
Choose a tag to compare

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