Qiskit / qiskit-aer

Aer is a high performance simulator for quantum circuits that includes noise models
https://qiskit.github.io/qiskit-aer/
Apache License 2.0
464 stars 354 forks source link

cuQuantum(cuStateVec) not invoked by statevector simulator #2144

Closed gjz010 closed 1 month ago

gjz010 commented 1 month ago

Informations

What is the current behavior?

AER::QV::QubitVectorThrust<data_t>::cuStateVec_enable() is invoked nowhere in the code, causing cuStateVec not being used even when cuStateVec_enable=True.

Steps to reproduce the problem

  1. Patch Qiskit Aer with the following debug lines:
    
    diff --git a/src/simulators/statevector/chunk/chunk_manager.hpp b/src/simulators/statevector/chunk/chunk_manager.hpp
    index 2e304515..9af66551 100644
    --- a/src/simulators/statevector/chunk/chunk_manager.hpp
    +++ b/src/simulators/statevector/chunk/chunk_manager.hpp
    @@ -21,6 +21,8 @@
    #include <spdlog/sinks/basic_file_sink.h>
    #include <spdlog/spdlog.h>

+#include + namespace AER { namespace QV { namespace Chunk { @@ -190,7 +192,7 @@ uint_t ChunkManager::Allocate(int chunk_bits, int nqubits, } //--- densitymatrix = density_mat;

  1. Run the following minimal example:
import numpy as np

# Import Qiskit
from qiskit import QuantumCircuit, transpile
from qiskit_aer import AerSimulator
from qiskit.visualization import plot_histogram, plot_state_city
import qiskit.quantum_info as qi
import matplotlib.pyplot as plt
# Create circuit
circ = QuantumCircuit(2)
circ.h(0)
circ.cx(0, 1)
circ.measure_all()

# Transpile for simulator
simulator = AerSimulator(method="statevector", device="GPU", cuStateVec_enable=True)
circ = transpile(circ, simulator)

# Run and get counts
result = simulator.run(circ).result()
counts = result.get_counts(circ)
print(counts)

What is the expected behavior?

The expected behaviour should be like:

Setting enable_cuStatevec as 1
{'0000000011': 487, '0000000000': 537}

Suggested solutions

The following patch fixed the issue for me.

diff --git a/src/simulators/statevector/statevector_state.hpp b/src/simulators/statevector/statevector_state.hpp
--- a/src/simulators/statevector/statevector_state.hpp
+++ b/src/simulators/statevector/statevector_state.hpp
@@ -433,6 +433,7 @@ void State<statevec_t>::initialize_omp() {
 template <class statevec_t>
 bool State<statevec_t>::allocate(uint_t num_qubits, uint_t block_bits,
                                  uint_t num_parallel_shots) {
+  BaseState::qreg_.cuStateVec_enable(BaseState::cuStateVec_enable_);
   if (BaseState::max_matrix_qubits_ > 0)
     BaseState::qreg_.set_max_matrix_bits(BaseState::max_matrix_qubits_);
   if (BaseState::max_sampling_shots_ > 0)