Template Class StateVectorCudaMPI

Inheritance Relationships

Base Type

Class Documentation

template<class Precision = double>
class StateVectorCudaMPI : public Pennylane::LightningGPU::StateVectorCudaBase<double, StateVectorCudaMPI<double>>

Managed memory CUDA state-vector class using custateVec backed gate-calls.

Template Parameters

Precision – Floating-point precision type.

Public Types

using CFP_t = typename StateVectorCudaBase<Precision, StateVectorCudaMPI<Precision>>::CFP_t
using PrecisionT = Precision
using ComplexT = std::complex<PrecisionT>
using MemoryStorageT = Pennylane::Util::MemoryStorageLocation::Undefined

Public Functions

StateVectorCudaMPI() = delete
inline StateVectorCudaMPI(MPIManager mpi_manager, const DevTag<int> &dev_tag, size_t mpi_buf_size, size_t num_global_qubits, size_t num_local_qubits)
inline StateVectorCudaMPI(MPI_Comm mpi_communicator, const DevTag<int> &dev_tag, size_t mpi_buf_size, size_t num_global_qubits, size_t num_local_qubits)
inline StateVectorCudaMPI(const DevTag<int> &dev_tag, size_t mpi_buf_size, size_t num_global_qubits, size_t num_local_qubits)
inline StateVectorCudaMPI(const DevTag<int> &dev_tag, size_t num_global_qubits, size_t num_local_qubits, const CFP_t *gpu_data)
inline StateVectorCudaMPI(const DevTag<int> &dev_tag, size_t num_global_qubits, size_t num_local_qubits)
inline StateVectorCudaMPI(const StateVectorCudaMPI &other)
~StateVectorCudaMPI() final = default
inline auto getMPIManager() const

Get MPI manager.

inline auto getTotalNumQubits() const -> size_t

Get the total number of wires.

inline auto getNumGlobalQubits() const -> size_t

Get the number of wires distributed across devices.

inline auto getNumLocalQubits() const -> size_t

Get the number of wires within the local devices.

inline auto getSwapWorker() -> custatevecSVSwapWorkerDescriptor_t

Get pointer to custatevecSVSwapWorkerDescriptor.

inline void setBasisState(const std::complex<Precision> &value, const size_t index, const bool async = false)

Set value for a single element of the state-vector on device. This method is implemented by cudaMemcpy.

Parameters
  • value – Value to be set for the target element.

  • index – Index of the target element.

  • async – Use an asynchronous memory copy.

template<class index_type, size_t thread_per_block = 256>
inline void setStateVector(const index_type num_indices, const std::complex<Precision> *values, const index_type *indices, const bool async = false)

Set values for a batch of elements of the state-vector. This method is implemented by the customized CUDA kernel defined in the DataBuffer class.

Parameters
  • num_indices – Number of elements to be passed to the state vector.

  • values – Pointer to values to be set for the target elements.

  • indices – Pointer to indices of the target elements.

  • async – Use an asynchronous memory copy.

inline void applyOperation(const std::string &opName, const std::vector<size_t> &wires, bool adjoint, const std::vector<Precision> &params, [[maybe_unused]] const std::vector<ComplexT> &matrix)

Apply a single gate to the state-vector. Offloads to custatevec specific API calls if available. If unable, attempts to use prior cached gate values on the device. Lastly, accepts a host-provided matrix if otherwise, and caches on the device for later reuse.

Parameters
  • opName – Name of gate to apply.

  • wires – Wires to apply gate to.

  • adjoint – Indicates whether to use adjoint of gate.

  • params – Optional parameter list for parametric gates.

  • matrix – Matrix representation of gate.

inline void applyOperation(const std::string &opName, const std::vector<size_t> &wires, bool adjoint = false, const std::vector<Precision> &params = {0.0}, [[maybe_unused]] const std::vector<CFP_t> &gate_matrix = {})

Apply a single gate to the state-vector. Offloads to custatevec specific API calls if available. If unable, attempts to use prior cached gate values on the device. Lastly, accepts a host-provided matrix if otherwise, and caches on the device for later reuse.

Parameters
  • opName – Name of gate to apply.

  • wires – Wires to apply gate to.

  • adjoint – Indicates whether to use adjoint of gate.

  • params – Optional parameter list for parametric gates.

  • gate_matrix – Matrix representation of gate.

template<template<typename...> class complex_t>
inline void applyOperation(const std::string &opName, const std::vector<std::size_t> &controlled_wires, const std::vector<bool> &controlled_values, const std::vector<std::size_t> &wires, bool inverse = false, const std::vector<Precision> &params = {0.0}, const std::vector<complex_t<Precision>> &gate_matrix = {})

Apply a single gate to the state vector.

Parameters
  • opName – Name of gate to apply.

  • controlled_wires – Control wires.

  • controlled_values – Control values (false or true).

  • wires – Wires to apply gate to.

  • inverse – Indicates whether to use adjoint of gate.

  • params – Optional parameter list for parametric gates.

  • gate_matrix – Optional std gate matrix if opName doesn’t exist.

inline auto applyGenerator(const std::string &opName, const std::vector<size_t> &wires, bool adjoint = false) -> PrecisionT

Apply a single generator to the state vector using the given kernel.

Parameters
  • opName – Name of gate to apply.

  • wires – Wires to apply gate to.

  • adjoint – Indicates whether to use adjoint of gate.

inline void applyMatrix(const std::complex<PrecisionT> *gate_matrix, const std::vector<size_t> &wires, bool adjoint = false)

Apply a given matrix directly to the statevector using a raw matrix pointer vector.

Parameters
  • matrix – Pointer to the array data (in row-major format).

  • wires – Wires to apply gate to.

  • adjoint – Indicate whether inverse should be taken.

inline void applyMatrix(const std::vector<std::complex<PrecisionT>> &gate_matrix, const std::vector<size_t> &wires, bool adjoint = false)

Apply a given matrix directly to the statevector using a std vector.

Parameters
  • matrix – Pointer to the array data (in row-major format).

  • wires – Wires to apply gate to.

  • adjoint – Indicate whether inverse should be taken.

inline void applyIdentity(const std::vector<std::size_t> &wires, bool adjoint)
inline void applyPauliX(const std::vector<std::size_t> &wires, bool adjoint)
inline void applyPauliY(const std::vector<std::size_t> &wires, bool adjoint)
inline void applyPauliZ(const std::vector<std::size_t> &wires, bool adjoint)
inline void applyHadamard(const std::vector<std::size_t> &wires, bool adjoint)
inline void applyS(const std::vector<std::size_t> &wires, bool adjoint)
inline void applyT(const std::vector<std::size_t> &wires, bool adjoint)
inline void applyRX(const std::vector<std::size_t> &wires, bool adjoint, Precision param)
inline void applyRY(const std::vector<std::size_t> &wires, bool adjoint, Precision param)
inline void applyRZ(const std::vector<std::size_t> &wires, bool adjoint, Precision param)
inline void applyRot(const std::vector<std::size_t> &wires, bool adjoint, Precision param0, Precision param1, Precision param2)
inline void applyRot(const std::vector<std::size_t> &wires, bool adjoint, const std::vector<Precision> &params)
inline void applyPhaseShift(const std::vector<std::size_t> &wires, bool adjoint, Precision param)
inline void applyCNOT(const std::vector<std::size_t> &wires, bool adjoint)
inline void applyCY(const std::vector<std::size_t> &wires, bool adjoint)
inline void applyCZ(const std::vector<std::size_t> &wires, bool adjoint)
inline void applySWAP(const std::vector<std::size_t> &wires, bool adjoint)
inline void applyIsingXX(const std::vector<std::size_t> &wires, bool adjoint, Precision param)
inline void applyIsingYY(const std::vector<std::size_t> &wires, bool adjoint, Precision param)
inline void applyIsingZZ(const std::vector<std::size_t> &wires, bool adjoint, Precision param)
inline void applyIsingXY(const std::vector<std::size_t> &wires, bool adjoint, Precision param)
inline void applyCRot(const std::vector<std::size_t> &wires, bool adjoint, const std::vector<Precision> &params)
inline void applyCRot(const std::vector<std::size_t> &wires, bool adjoint, Precision param0, Precision param1, Precision param2)
inline void applyCRX(const std::vector<std::size_t> &wires, bool adjoint, Precision param)
inline void applyCRY(const std::vector<std::size_t> &wires, bool adjoint, Precision param)
inline void applyCRZ(const std::vector<std::size_t> &wires, bool adjoint, Precision param)
inline void applyControlledPhaseShift(const std::vector<std::size_t> &wires, bool adjoint, Precision param)
inline void applySingleExcitation(const std::vector<std::size_t> &wires, bool adjoint, Precision param)
inline void applySingleExcitationMinus(const std::vector<std::size_t> &wires, bool adjoint, Precision param)
inline void applySingleExcitationPlus(const std::vector<std::size_t> &wires, bool adjoint, Precision param)
inline void applyToffoli(const std::vector<std::size_t> &wires, bool adjoint)
inline void applyCSWAP(const std::vector<std::size_t> &wires, bool adjoint)
inline void applyDoubleExcitation(const std::vector<std::size_t> &wires, bool adjoint, Precision param)
inline void applyDoubleExcitationMinus(const std::vector<std::size_t> &wires, bool adjoint, Precision param)
inline void applyDoubleExcitationPlus(const std::vector<std::size_t> &wires, bool adjoint, Precision param)
inline void applyMultiRZ(const std::vector<std::size_t> &wires, bool adjoint, Precision param)
inline PrecisionT applyGeneratorRX(const std::vector<size_t> &wires, bool adj = false)

Gradient generator function associated with the RX gate.

Parameters
  • sv – Statevector

  • wires – Wires to apply operation.

  • adj – Takes adjoint of operation if true. Defaults to false.

inline PrecisionT applyGeneratorRY(const std::vector<size_t> &wires, bool adj = false)

Gradient generator function associated with the RY gate.

Parameters
  • sv – Statevector

  • wires – Wires to apply operation.

  • adj – Takes adjoint of operation if true. Defaults to false.

inline PrecisionT applyGeneratorRZ(const std::vector<size_t> &wires, bool adj = false)

Gradient generator function associated with the RZ gate.

Parameters
  • sv – Statevector

  • wires – Wires to apply operation.

  • adj – Takes adjoint of operation if true. Defaults to false.

inline PrecisionT applyGeneratorIsingXX(const std::vector<std::size_t> &wires, bool adjoint)
inline PrecisionT applyGeneratorIsingYY(const std::vector<std::size_t> &wires, bool adjoint)
inline PrecisionT applyGeneratorIsingZZ(const std::vector<std::size_t> &wires, bool adjoint)
inline PrecisionT applyGeneratorIsingXY(const std::vector<std::size_t> &wires, bool adjoint)
inline PrecisionT applyGeneratorPhaseShift(const std::vector<size_t> &wires, bool adj = false)

Gradient generator function associated with the PhaseShift gate.

Parameters
  • wires – Wires to apply operation.

  • adj – Takes adjoint of operation if true. Defaults to false.

inline PrecisionT applyGeneratorCRX(const std::vector<size_t> &wires, bool adj = false)

Gradient generator function associated with the controlled RX gate.

Parameters
  • wires – Wires to apply operation.

  • adj – Takes adjoint of operation if true. Defaults to false.

inline PrecisionT applyGeneratorCRY(const std::vector<size_t> &wires, bool adj = false)

Gradient generator function associated with the controlled RY gate.

Parameters
  • wires – Wires to apply operation.

  • adj – Takes adjoint of operation if true. Defaults to false.

inline PrecisionT applyGeneratorCRZ(const std::vector<size_t> &wires, bool adj = false)

Gradient generator function associated with the controlled RZ gate.

Parameters
  • wires – Wires to apply operation.

  • adj – Takes adjoint of operation if true. Defaults to false.

inline PrecisionT applyGeneratorControlledPhaseShift(const std::vector<size_t> &wires, bool adj = false)

Gradient generator function associated with the controlled PhaseShift gate.

Parameters
  • wires – Wires to apply operation.

  • adj – Takes adjoint of operation if true. Defaults to false.

inline PrecisionT applyGeneratorSingleExcitation(const std::vector<std::size_t> &wires, bool adjoint)
inline PrecisionT applyGeneratorSingleExcitationMinus(const std::vector<std::size_t> &wires, bool adjoint)
inline PrecisionT applyGeneratorSingleExcitationPlus(const std::vector<std::size_t> &wires, bool adjoint)
inline PrecisionT applyGeneratorDoubleExcitation(const std::vector<std::size_t> &wires, bool adjoint)
inline PrecisionT applyGeneratorDoubleExcitationMinus(const std::vector<std::size_t> &wires, bool adjoint)
inline PrecisionT applyGeneratorDoubleExcitationPlus(const std::vector<std::size_t> &wires, bool adjoint)
inline PrecisionT applyGeneratorMultiRZ(const std::vector<std::size_t> &wires, bool adjoint)
inline auto getCublasCaller() const -> const CublasCaller&

Access the CublasCaller the object is using.

Returns

a reference to the object’s CublasCaller object.

inline auto getCusparseHandle() const -> cusparseHandle_t

Get the cuSPARSE handle that the object is using.

Returns

cusparseHandle_t returns the cuSPARSE handle.

inline auto getCusvHandle() const -> custatevecHandle_t

Get the cuStateVec handle that the object is using.

Returns

custatevecHandle_t returns the cuStateVec handle.

inline auto getDataVector() -> std::vector<std::complex<PrecisionT>>

Get a host data copy.

Returns

std::vector<std::complex<PrecisionT>>

inline auto expval(const std::string &obsName, const std::vector<size_t> &wires, const std::vector<Precision> &params = {0.0}, const std::vector<CFP_t> &gate_matrix = {})

Utility method for expectation value calculations.

Parameters
  • obsName – String label for observable. If already exists, will used cached device value. If not, gate_matrix is expected, and will automatically cache for future reuse.

  • wires – Target wires for expectation value.

  • params – Parameters for a parametric gate.

  • gate_matrix – Optional matrix for observable. Caches for future use if does not exist.

Returns

auto Expectation value.

inline auto expval(const std::vector<size_t> &wires, const std::vector<std::complex<Precision>> &gate_matrix)

See expval(std::vector<CFP_t> &gate_matrix = {})

inline auto getExpectationValuePauliWords(const std::vector<std::string> &pauli_words, const std::vector<std::vector<std::size_t>> &tgts, const std::complex<Precision> *coeffs)

Get expectation value for a sum of Pauli words. This function accepts a vector of words, where each word contains a set of Pauli operations along with their corresponding wires and coefficients of the Hamiltonian. The expval calculation is performed based on the word and its corresponding target wires. The distribution of target wires can be categorized into three different types:1. All target wires are local, and no MPI operation is required. 2. Some target wires are located at the global wires, and there are sufficient local wires available for bit swap operations. 3. Some target wires are located at the global wires, and there are insufficient local wires available for bit swap operations. For the first scenario, the expvalOnPauliBasis method can be called directly to obtain the expval. In the second scenario, bit swap operations are necessary before and after the expvalOnPauliBasis operation to get the expval. In the third scenario, a temporary state vector is created to calculate the bra, and then the inner product is used to calculate the expval. This function here will check the corresponding target wires of all word first. If all target wires for each word are local, the expvalOnPauliBasis will be called just once. Otherwise, each word will be looped and corresponding expval calculation methods will be adopted.

Parameters
  • pauli_words – Vector of Pauli-words to evaluate expectation value.

  • tgts – Coupled qubit index to apply each Pauli term.

  • coeffs – Numpy array buffer of size |pauli_words|

Returns

auto Expectation value.