QuEST (Quantum Exact Simulation Toolkit)

repository·main·Indexed 19 days ago

https://github.com/quest-kit/quest

A high-performance, hybrid simulator for quantum statevectors and density matrices. Optimized for CPUs, GPUs, and distributed supercomputing environments, QuEST supports multithreading via OpenMP, distribution via MPI, and GPU acceleration via CUDA or HIP/ROCm. It provides C and C++ interfaces for simulating quantum algorithms, handling decoherence and noise, and performing complex quantum operations across various hardware configurations.

Tokens
17.7K
Snippets
60
Records
82
Agent score
67%

What's inside QuEST

  1. Overview of QuEST (Quantum Exact Simulation Toolkit)

    main

    QuEST is a high-performance simulator for quantum statevectors and density matrices. It is designed to run efficiently across various hardware configurations, including laptops, desktops, and supercomputers, by hybridizing multithreading, GPU acceleration, and distribution.

    Key capabilities include:

    • Simulation Modes: Supports both statevector and density matrix simulations (for noisy quantum computers).
    • Hardware Abstraction: Automatically decides at runtime whether to use CPUs (via OpenMP), distributed systems (via MPI), or GPUs (via CUDA or HIP/ROCm).
    • Performance Optimizations: Leverages technologies like NVLink, cuQuantum, and GPUDirect for multi-GPU clusters.
    • Numerical Precision: Provides variable precision through qreal and qcomp types (single, double, or quad precision).
    • Language Support: Accessible via C and C++ interfaces and compatible with all major compilers on MacOS, Linux, and Windows.
  2. Key features and improvements in QuEST v4

    main

    QuEST v4 introduces a complete overhaul of the API, software architecture, and algorithms. Key improvements for users include:

    • Auto-deployer: Functions like createQureg() and createFullStateDiagMatr() automatically select the optimal hardware (multithreading, GPU acceleration, or distribution) based on simulation size and available memory.
    • Heterogeneous Deployments: Supports multiple GPUs, distributed computing across networks, and high-bandwidth interconnects (like NVLink). Different Qureg instances can use different hardware facilities simultaneously.
    • Performance: Backend algorithms have been replaced with optimized routines (documented in arXiv 2311.0512), featuring compile-time optimizations and lazy evaluation of properties like matrix unitarity.
    • Cleaner API: Consistent function naming, support for qcomp (an arithmetic-overloaded complex scalar type), and easier initialization of Matrices and Pauli tensors using matrix or string literals.
    • Reporters: New utilities for printing data structures (states, operators, scalars) and reporting on the environment and hardware acceleration usage.
    • Expanded Operations: Support for arbitrary control qubits in unitaries, raising diagonal matrices to powers, partial tracing, inhomogeneous Pauli channels, Kraus maps, superoperators, and multi-qubit projectors (with or without renormalization).
    • Debugging & Control: Facilities to disable or change validation precision and error responses at runtime, and control the number of amplitudes or significant figures printed.
  3. Understand the purpose of isolated examples

    main

    The examples/isolated directory contains examples designed to demonstrate the specific uses of individual QuEST functions or facilities. Unlike full application examples, these are focused on illustrating the various ways a single task (e.g., initializing a KrausMap) can be performed using the QuEST API.

    Each example is provided in both C and C++ versions to showcase the specific interfaces available to each language. The C examples are compiled against the C11 standard, and the C++ examples are compiled against C++17.

  4. Understand the QuEST v4 modular architecture

    main

    QuEST v4 is built on a highly modular architecture that separates concerns into distinct modules:

    • Interfacing: quest/src/api handles the public API.
    • Validation: quest/src/core/validation.cpp validates user input.
    • Core Pre-processing: quest/src/core/ manages logic including:
      • Autodeploying: quest/src/core/autodeployer.cpp
      • Inlining: quest/src/core/inliner.hpp
      • Math/Bitwise: quest/src/core/fastmath.hpp and quest/src/core/bitwise.hpp
      • Memory Probing: quest/src/core/memory.cpp
      • Error/Precondition Checking: quest/src/core/errors.cpp
      • Parsing/Printing: quest/src/core/parser.cpp and quest/src/core/printer.cpp
      • Randomization: quest/src/core/randomiser.cpp
    • Data Management: Localizing (quest/src/core/localiser.cpp) and distributing (quest/src/comm/comm_routines.cpp) data.
    • Acceleration: Choosing and executing via CPUs (quest/src/cpu/) or GPUs (quest/src/gpu/).

    The backend is implemented in C++17, utilizing modern features like templates, namespaces, and smart pointers, while maintaining a C-compatible frontend.

  5. Accurate benchmarking in distributed QuEST

    main

    In distributed mode, QuEST nodes work independently and only synchronize during specific operations (like calcTotalProb()) or when explicitly forced. This can lead to desynchronization where one node finishes while others are still working, making CPU/memory monitoring and simple timers inaccurate.

    To ensure performance timers reflect the runtime of the entire calculation (the slowest node), you must explicitly call syncQuESTEnv() immediately before starting and immediately before ending your timer.

    // Recommended pattern for benchmarking
    syncQuESTEnv();
    start_timer();
    
    // ... perform simulation ...
    
    syncQuESTEnv();
    stop_timer();
  6. Compiler requirements for QuEST Backend

    main
    The QuEST backend (comprising api/, core/, comm/, cpu/, and gpu/) requires a C++17 compiler. While all components can be compiled with a generic C++17 compiler, specific features like distribution, multithreading, and GPU acceleration require specialized compilers. Each component can be toggled and compiled independently.
  7. Understand the QuEST software architecture and control flow

    main

    QuEST follows a layered architecture that moves from high-level API calls to low-level hardware acceleration. Understanding this flow helps in debugging and understanding how inputs are processed:

    1. API Layer (include/quest.h & api/): The entry point. Functions here validate user inputs using core/validation.cpp (which checks RAM, VRAM, and distributed config) and then call core/ functions.
    2. Core Layer (core/): Handles internal logic including validation, memory management, utilities, and the localiser. The localiser determines if data needs to be exchanged across distributed nodes via the comm/ layer.
    3. Accelerator Layer (core/accelerator): The dispatch stage. It decides whether to use the CPU or GPU backend based on the workload and available hardware.
    4. Backend Layer (cpu/ & gpu/): The execution stage.
      • CPU: Uses OpenMP-accelerated subroutines.
      • GPU: Uses CUDA-accelerated subroutines, custom kernels, Thrust, or cuQuantum (if compiled).
  8. Use controlled operations and control states

    main

    Most unitary operations in QuEST support control qubits. You can specify a list of controls to trigger the operation. Additionally, you can use control states, which are bit arrays specifying whether a control qubit must be in state 0 or 1 to trigger the operation.

    Language Tips:

    • C users: Use compound literals to pass inline lists.
    • C++ users: Use initializer lists (e.g., {0, 1, 2}) to avoid manually specifying list lengths.
    // Multi-controlled operation
    int controls[] = {0,1,2,3,7,8,9};
    applyMultiControlledSqrtSwap(qureg, controls, 7, targets[0], targets[1]);
    
    // Multi-state controlled operation
    int states[] = {0,0,0,1,1,1,0};
    applyMultiStateControlledRotateX(qureg, controls, states, target, angle);
  9. How to use the QuEST API

    main

    All user-visible API signatures are provided through a single header file, quest.h. While the API is organized into semantic submodules within the include/ directory (such as calculations.h and qureg.h), you should include quest.h to access the full suite of functions.

    All exposed functions are strictly C and C++ compatible, making the library easy to integrate into both C and C++ projects.

    #include <quest.h>
    // All API functions are accessible via this single header
  10. Getting started with QuEST

    main

    To begin using QuEST, follow these steps to set up your environment and run simulations:

    1. Check Compiler Compatibility: Verify your compiler against the list in compilers.md.
    2. Download Compilers: If needed, visit qtechtheory.org for assistance.
    3. Compile QuEST: Follow the instructions in compile.md to build the library.
    4. Configure via CMake: Use the variables defined in cmake.md to customize your build.
    5. Run Simulations: Refer to launch.md for guidance on running QuEST on various hardware, ranging from laptops to supercomputers.
    6. Learn the API: For detailed function documentation, consult the official API reference.
    7. Follow the Tutorial: For a guided introduction, use tutorial.md.
  11. Run QuEST tests

    main

    If ENABLE_TESTING is enabled, you can run tests from the build directory using one of the following methods:

    1. Using Make: make test
    2. Using CTest: ctest
    3. Manual Launch: ./tests/tests (Note: This enables distribution, e.g., mpirun -np 8 ./tests/tests)

    To run deprecated (v3) API tests specifically:

    1. cd tests/deprecated
    2. ctest or ./tests/deprecated/dep_tests
  12. Report and format results

    main

    QuEST provides several functions to report data structures to the console with pretty formatting. The output is controlled by reporter settings.

    Reporting Functions

    • reportPauliStr: Reports a Pauli string.
    • reportPauliStrSum: Reports a weighted sum of Pauli strings.
    • reportCompMatr: Reports a complex matrix.
    • reportScalar: Reports a single real or complex number.

    Reporter Settings

    Use these to control the verbosity and precision of the output:

    • setMaxNumReportedItems(rows, cols): Limits the number of items displayed in matrices.
    • setMaxNumReportedSigFigs(n): Sets the number of significant figures for reported numbers.
    // Reporting a Pauli string sum
    reportPauliStrSum(sum);
    
    // Configuring reporter settings for a matrix
    setMaxNumReportedItems(4,4);
    setMaxNumReportedSigFigs(1);
    reportCompMatr(bigmatrix);