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
470 stars 353 forks source link

Segfault when running certain circuits with the GPU statevector simulator, `AerPauliExpectation`, and certain noise models #1647

Closed HaoTy closed 1 year ago

HaoTy commented 1 year ago

Informations

What is the current behavior?

Running certain circuits (e.g. the QAOA expectation value of an 18-qubit SKModel instance, see below) with the GPU statevector simulator, AerPauliExpectation, and certain noise models (e.g. 2-qubit depolar error) causes segmentation fault. Using the CPU statevector simulator does not have this issue. Some other circuits, for example, the QAOA expectation value of the Maxcut problem, do not have this issue. Some other noise models, including ideal simulations, Pauli errors, and 1-qubit depolar errors, do not have this issue. 16 qubits or below do not have this issue (the exact number may depend on machine specs).

Steps to reproduce the problem

import numpy as np
import networkx as nx
from qiskit_aer import AerSimulator
from qiskit_aer.noise import NoiseModel
from qiskit_aer.noise.errors.standard_errors import depolarizing_error
from qiskit.algorithms import QAOA
from qiskit.algorithms.optimizers import SPSA
from qiskit.utils import QuantumInstance
from qiskit.opflow import AerPauliExpectation
from qiskit_optimization.applications import Maxcut, SKModel
from qiskit.utils import algorithm_globals
from docplex.mp.model import Model

n = 18
p = 1
seed = 0

# Maxcut does not produce segfault
# graph = nx.random_regular_graph(3, n, seed)
# problem = Maxcut(graph).to_quadratic_program()

# SKModel with n=18 or more produces segfault
problem = SKModel(n, seed).to_quadratic_program()

# Some other problems can also cause this issue
# number_set = np.random.default_rng(seed).integers(2 ** (n // 2), size=n) + 1
# mdl = Model(name="Number partitioning")
# x = {i: mdl.binary_var(name=f"x_{i}") for i in range(n)}
# mdl.minimize(mdl.sum(num * (-2 * x[i] + 1) for i, num in enumerate(number_set)) ** 2)
# problem = from_docplex_mp(mdl)

H, offset = problem.to_ising()

noise_model = NoiseModel()
noise_model.add_all_qubit_quantum_error(depolarizing_error(0.01, 2), 'cx')
algorithm_globals.random_seed = seed
backend = AerSimulator(method="statevector", device="GPU", noise_model=noise_model)
quantum_instance = QuantumInstance(
    backend=backend,
    seed_simulator=seed,
    seed_transpiler=seed,
)

algorithm = QAOA(
    SPSA(),
    reps=p,
    quantum_instance=quantum_instance,
    expectation=AerPauliExpectation(),
)
algorithm._check_operator_ansatz(H)
energy_evaluation= algorithm.get_energy_evaluation(H)
parameters = 2 * np.pi * np.random.default_rng(seed).random(2 * p)
energy_evaluation(parameters)

What is the expected behavior?

The simulator should be able to evaluate the QAOA energy without causing segfault.

doichanj commented 1 year ago

This issue is caused by gate fusion. Some operations inserted by noise model are fused and fused unitary matrix is larger than matrix buffer allocated on GPU. I will fix this issue by searching max matrix qubits after fusion Until the fix will be released, please disable fusion by setting fusion_threshold=30 (larger than circuits qubits)

HaoTy commented 1 year ago

Thanks for the quick help! I can confirm that disabling fusion is an effective workaround.

hhorii commented 1 year ago

I would like to create a new issue for segmentation faults due to massive cp gates.