Skip to content

Commit

Permalink
Fix test suite to work with Qiskit<1.0 and >=1.0
Browse files Browse the repository at this point in the history
This commit *does not* touch the primitives, which appear to be broken
at a relatively basic level with Qiskit 1.0 - hopefully the primitives
team can fix that separately.

This modifies the test suite to work with both Qiskit 0.46 and 1.0.0rc1
simultaneously.  Unfortunately, some of the new-style fake backends
aren't in 0.46, so I just put in some import switches for my ease here.
A few tests, particularly in the noise model sections, were asserting
specific things about the properties/calibrations of Terra's fake
backends, which was quite fragile already, so in those particular cases
I replaced them with a manually constructed `Target` with properties
entirely under Aer's control.
  • Loading branch information
jakelishman committed Feb 2, 2024
1 parent 891a451 commit 1ba6190
Show file tree
Hide file tree
Showing 7 changed files with 151 additions and 142 deletions.
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ $ python
```python
import qiskit
from qiskit_aer import AerSimulator
from qiskit.providers.fake_provider import FakeManilaV2
from qiskit_ibm_runtime import QiskitRuntimeService

# Generate 3-qubit GHZ state
circ = qiskit.QuantumCircuit(3)
Expand All @@ -73,10 +73,10 @@ counts_ideal = result_ideal.get_counts(0)
print('Counts(ideal):', counts_ideal)
# Counts(ideal): {'000': 493, '111': 531}

# Construct a noisy simulator backend from an IBMQ backend
# This simulator backend will be automatically configured
# using the device configuration and noise model
backend = FakeManilaV2()
# Construct a simulator using a noise model
# from a real backend.
provider = QiskitRuntimeService()
backend = provider.get_backend("ibm_kyoto")
aersim_backend = AerSimulator.from_backend(backend)

# Perform noisy simulation
Expand Down
54 changes: 0 additions & 54 deletions test/terra/backends/aer_simulator/test_from_backend.py

This file was deleted.

14 changes: 10 additions & 4 deletions test/terra/backends/aer_simulator/test_options.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,18 @@
"""

from ddt import ddt, data
from qiskit import QuantumCircuit, transpile
from qiskit_aer.noise import NoiseModel
from test.terra.backends.simulator_test_case import SimulatorTestCase, supported_methods

import qiskit
from qiskit import QuantumCircuit, transpile
from qiskit.quantum_info.random import random_unitary
from qiskit.quantum_info import state_fidelity
from qiskit.providers.fake_provider import FakeMontreal

if qiskit.__version__.startswith("0."):
from qiskit.providers.fake_provider import FakeAlmaden as Fake20QV1
else:
from qiskit.providers.fake_provider import Fake20QV1

from qiskit_aer import AerSimulator

Expand Down Expand Up @@ -299,8 +305,8 @@ def test_statevector_memory(self):
def test_num_qubits(self, method):
"""Test number of qubits is correctly checked"""

num_qubits = FakeMontreal().configuration().num_qubits
backend = AerSimulator.from_backend(FakeMontreal(), method=method)
num_qubits = Fake20QV1().configuration().num_qubits
backend = AerSimulator.from_backend(Fake20QV1(), method=method)
self.assertGreaterEqual(backend.configuration().num_qubits, num_qubits)

def test_mps_svd_method(self):
Expand Down
10 changes: 8 additions & 2 deletions test/terra/backends/aer_simulator/test_truncate.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,14 @@
AerSimulator Integration Tests
"""
from ddt import ddt

import qiskit
from qiskit import transpile, QuantumCircuit
from qiskit.providers.fake_provider import FakeQuito
if qiskit.__version__.startswith("0."):
from qiskit.providers.fake_provider import FakeQuito as Fake5QV1
else:
from qiskit.providers.fake_provider import Fake5QV1

from qiskit_aer.noise import NoiseModel
from test.terra.backends.simulator_test_case import SimulatorTestCase, supported_methods

Expand Down Expand Up @@ -46,7 +52,7 @@ def create_circuit_for_truncate(self):
return circuit

def device_backend(self):
return FakeQuito()
return Fake5QV1()

def test_truncate_ideal_sparse_circuit(self):
"""Test qubit truncation for large circuit with unused qubits."""
Expand Down
75 changes: 64 additions & 11 deletions test/terra/noise/test_device_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,29 +16,77 @@
import numpy as np
from test.terra.common import QiskitAerTestCase

from qiskit.circuit.library.standard_gates import XGate
from qiskit.providers.fake_provider import FakeNairobi, FakeNairobiV2
from qiskit.transpiler import Target, QubitProperties, InstructionProperties
import qiskit
from qiskit.circuit import library, Reset, Measure, Parameter
from qiskit.providers import convert_to_target
from qiskit.transpiler import CouplingMap, Target, QubitProperties, InstructionProperties

if qiskit.__version__.startswith("0."):
from qiskit.providers.fake_provider import FakeQuito as Fake5QV1
else:
from qiskit.providers.fake_provider import Fake5QV1

from qiskit_aer.noise.device.models import basic_device_gate_errors
from qiskit_aer.noise.errors.standard_errors import thermal_relaxation_error


def target_7q():
"""Build an arbitrary 7q ``Target`` with noisy instructions."""
num_qubits = 7
qubit_properties = [
QubitProperties(t1=1.5e-4, t2=1.5e-4, frequency=4_700_000_000.0 + q*50_000_000.0)
for q in range(num_qubits)
]
target = Target(num_qubits=7, qubit_properties=qubit_properties)
for gate in (library.SXGate(), library.XGate(), library.RZGate(Parameter("a"))):
target.add_instruction(
gate,
properties={
(q,): InstructionProperties(duration=50e-9, error=2e-4)
for q in range(num_qubits)
},
)
target.add_instruction(
library.CXGate(),
properties={
link: InstructionProperties(duration=300e-9, error=1e-3)
for link in CouplingMap.from_ring(num_qubits)
},
)
target.add_instruction(
Reset(),
properties={
(q,): InstructionProperties(duration=4e-6, error=None)
for q in range(num_qubits)
},
)
target.add_instruction(
Measure(),
properties={
(q,): InstructionProperties(duration=3e-6, error=1.5e-2)
for q in range(num_qubits)
},
)
return target



class TestDeviceNoiseModel(QiskitAerTestCase):
"""Testing device noise model"""

def test_basic_device_gate_errors_from_target(self):
"""Test if the resulting gate errors never include errors on non-gate instructions"""
target = FakeNairobiV2().target
target = target_7q()
gate_errors = basic_device_gate_errors(target=target)
errors_on_measure = [name for name, _, _ in gate_errors if name == "measure"]
errors_on_reset = [name for name, _, _ in gate_errors if name == "reset"]
self.assertEqual(len(errors_on_measure), 0)
self.assertEqual(len(errors_on_reset), 7)
self.assertEqual(len(gate_errors), 40)
self.assertEqual(len(gate_errors), 42)

def test_basic_device_gate_errors_from_target_with_non_operational_qubits(self):
"""Test if no thermal relaxation errors are generated for qubits with undefined T1 and T2."""
target = FakeNairobiV2().target
target = target_7q()
# tweak target to have non-operational qubits
faulty_qubits = (1, 2)
for q in faulty_qubits:
Expand All @@ -47,7 +95,7 @@ def test_basic_device_gate_errors_from_target_with_non_operational_qubits(self):
gate_errors = basic_device_gate_errors(target=target, gate_error=False)
errors_on_sx = {qubits: error for name, qubits, error in gate_errors if name == "sx"}
errors_on_cx = {qubits: error for name, qubits, error in gate_errors if name == "cx"}
self.assertEqual(len(gate_errors), 40)
self.assertEqual(len(gate_errors), 42)
# check if no errors are added on sx gates on qubits without T1 and T2 definitions
for q in faulty_qubits:
self.assertTrue(errors_on_sx[(q,)].ideal())
Expand All @@ -56,8 +104,13 @@ def test_basic_device_gate_errors_from_target_with_non_operational_qubits(self):

def test_basic_device_gate_errors_from_target_and_properties(self):
"""Test if the device same gate errors are produced both from target and properties"""
errors_from_properties = basic_device_gate_errors(properties=FakeNairobi().properties())
errors_from_target = basic_device_gate_errors(target=FakeNairobiV2().target)
backend = Fake5QV1()
target = convert_to_target(
configuration=backend.configuration(),
properties=backend.properties(),
)
errors_from_properties = basic_device_gate_errors(properties=backend.properties())
errors_from_target = basic_device_gate_errors(target=target)
self.assertEqual(len(errors_from_properties), len(errors_from_target))
errors_from_properties_s = sorted(errors_from_properties)
errors_from_target_s = sorted(errors_from_target)
Expand All @@ -71,7 +124,7 @@ def test_basic_device_gate_errors_from_target_and_properties(self):
def test_basic_device_gate_errors_from_target_with_no_t2_value(self):
"""Test if gate errors are successfully created from a target with qubits not reporting T2.
See https://github.com/Qiskit/qiskit-aer/issues/1896 for the details."""
target = FakeNairobiV2().target
target = target_7q()
target.qubit_properties[0].t2 = None
basic_device_gate_errors(target=target)

Expand All @@ -80,7 +133,7 @@ def test_non_zero_temperature(self):
See https://github.com/Qiskit/qiskit-aer/issues/1937 for the details."""
t1, t2, frequency, duration = 1e-4, 1e-4, 5e9, 5e-8
target = Target(qubit_properties=[QubitProperties(t1=t1, t2=t2, frequency=frequency)])
target.add_instruction(XGate(), {(0,): InstructionProperties(duration=duration)})
target.add_instruction(library.XGate(), {(0,): InstructionProperties(duration=duration)})
errors = basic_device_gate_errors(target=target, gate_error=False, temperature=100)
_, _, x_error = errors[0]
no_excitation_error = thermal_relaxation_error(t1, t2, duration, excited_state_population=0)
Expand Down
Loading

0 comments on commit 1ba6190

Please sign in to comment.