Skip to content

Commit

Permalink
General update to bring the main branch up to date (#1471)
Browse files Browse the repository at this point in the history
### Summary

A few main changes
- Update the pylint to the latest version and fix errors
- Update workflows to python 3.9 (3.8 is EOL and does not work with the
latest packages)
- Fix deprecation warnings
- Fix small bug in tomo
- Any other housekeeping

---------

Co-authored-by: Will Shanks <willshanks@us.ibm.com>
  • Loading branch information
dcmckayibm and wshanks authored Sep 30, 2024
1 parent 7a0924c commit 02572a3
Show file tree
Hide file tree
Showing 29 changed files with 67 additions and 41 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/cron-staging.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
python-version: [3.8, "3.12"]
python-version: [3.9, "3.12"]
os: ["ubuntu-latest", "macos-latest", "windows-latest"]
steps:
- name: Print Concurrency Group
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
python-version: [3.8, "3.12"]
python-version: [3.9, "3.12"]
os: ["ubuntu-latest", "macos-latest", "windows-latest"]
steps:
- name: Print Concurrency Group
Expand Down Expand Up @@ -67,10 +67,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python 3.8
- name: Set up Python 3.9
uses: actions/setup-python@v5
with:
python-version: 3.8
python-version: 3.9
- name: Pip cache
uses: actions/cache@v4
with:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
- uses: actions/setup-python@v5
name: Install Python
with:
python-version: '3.8'
python-version: '3.9'
- name: Install Deps
run: pip install -U wheel
- name: Build Artifacts
Expand Down
4 changes: 2 additions & 2 deletions .pylintrc
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ disable=fixme, # disabled as TODOs would show up as warnings
cyclic-import, # This checker raises on all module pairs that import each other,
# even submodules that only import already loaded objects from a
# parent module, a common pattern in qiskit-experiments.
assigning-non-slot # https://github.com/Qiskit/qiskit/pull/7347#issuecomment-985007311

assigning-non-slot, # https://github.com/Qiskit/qiskit/pull/7347#issuecomment-985007311
too-many-positional-arguments



Expand Down
2 changes: 1 addition & 1 deletion qiskit_experiments/framework/backend_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
Since `BackendV1` and `BackendV2` do not share the same interface, this
class unifies data access for various data fields.
"""
from qiskit.providers.models import PulseBackendConfiguration
from qiskit.providers.models import PulseBackendConfiguration # pylint: disable=no-name-in-module
from qiskit.providers import BackendV1, BackendV2


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,10 @@ def _combined_circuits(self, device_layout: bool) -> List[QuantumCircuit]:
# Apply transpiled subcircuit
# Note that this assumes the circuit was not expanded to use
# any qubits outside the specified physical qubits
for inst, qargs, cargs in sub_circ.data:
for data in sub_circ.data:
inst = data.operation
qargs = data.qubits
cargs = data.clbits
mapped_cargs = [sub_cargs[sub_circ.find_bit(i).index] for i in cargs]
try:
mapped_qargs = [
Expand Down
2 changes: 1 addition & 1 deletion qiskit_experiments/framework/experiment_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -602,7 +602,7 @@ def _set_hgp_from_provider(self, provider):
self.hgp = hgp_string
break
except (AttributeError, IndexError, QiskitError):
return
pass

@property
def hgp(self) -> str:
Expand Down
2 changes: 1 addition & 1 deletion qiskit_experiments/framework/json.py
Original file line number Diff line number Diff line change
Expand Up @@ -566,7 +566,7 @@ def object_hook(self, obj):
return load_obj
if obj_type == "Instruction":
circuit = _decode_and_deserialize(obj_val, qpy.load, name="QuantumCircuit")[0]
return circuit.data[0][0]
return circuit.data[0].operation
if obj_type == "QuantumCircuit":
return _decode_and_deserialize(obj_val, qpy.load, name=obj_type)[0]
if obj_type == "ScheduleBlock":
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,7 @@ class EchoedCrossResonanceHamiltonian(CrossResonanceHamiltonian):
.. ref_arxiv:: 1 2007.02925
"""

num_pulses = 2

def _build_cr_circuit(self, pulse_gate: circuit.Gate) -> QuantumCircuit:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ def _spam_cal_circuits(self, meas_circuit: QuantumCircuit) -> List[QuantumCircui
circ = QuantumCircuit(self.num_qubits, meas_circuit.num_clbits)

if add_x:
qubits = meas_circuit.get_instructions("measure")[0][1]
qubits = meas_circuit.get_instructions("measure")[0].qubits
circ.x(qubits)

circ.compose(meas_circuit, inplace=True)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ def __init__(
delay_ops = [delay.operation for delay in interleaved_element.get_instructions("delay")]
if delay_ops:
timing = BackendTiming(backend)
else:
timing = None
for delay_op in delay_ops:
if delay_op.unit != timing.delay_unit:
raise QiskitError(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,9 @@ def _transpiled_circuits(self) -> List[QuantumCircuit]:
for circ in transpiled:
count_ops_result = defaultdict(int)
# This is physical circuits, i.e. qargs is physical index
for inst, qargs, _ in circ.data:
for cdata in circ.data:
inst = cdata.operation
qargs = cdata.qubits
if inst.name in ("measure", "reset", "delay", "barrier", "snapshot"):
continue
qinds = [qubit_indices[q] for q in qargs]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ def trace_preserving_constaint(

# If not hermitian add imaginary partial trace constraint
if isinstance(mat_i, (tuple, list)):
arg_r = cvxpy.sum(mat_i)
arg_i = cvxpy.sum(mat_i)
elif isinstance(mat_i, Variable):
arg_i = mat_i
else:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ def lstsq_data(
cdim = 1
num_meas_cond = 0
num_prep_cond = 0
bsize = None

# Get full and conditional measurement basis dimensions
if measurement_basis:
Expand Down
9 changes: 6 additions & 3 deletions qiskit_experiments/test/mock_iq_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,10 @@ def _parallel_exp_circ_splitter(self, qc_list: List[QuantumCircuit]):

# sorting instructions by qubits indexes and inserting them into a circuit of the relevant
# experiment
for inst, qarg, carg in qc.data:
for data in qc.data:
inst = data.operation
qarg = data.qubits
carg = data.clbits
qubit_indices = set(qc.find_bit(qr).index for qr in qarg)
for qubits, exp_idx in qubits_expid_map.items():
if qubit_indices.issubset(qubits):
Expand Down Expand Up @@ -599,8 +602,8 @@ def compute_probabilities(self, circuits: List[QuantumCircuit]) -> List[Dict[str
probability_output_dict = {}
delay = None
for instruction in circuit.data:
if instruction[0].name == "delay":
delay = instruction[0].duration
if instruction.operation.name == "delay":
delay = instruction.operation.duration

if delay is None:
probability_output_dict = {"1": 1, "0": 0}
Expand Down
4 changes: 2 additions & 2 deletions qiskit_experiments/test/pulse_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
from qiskit.circuit.measure import Measure
from qiskit.circuit.parameter import Parameter
from qiskit.providers import BackendV2, QubitProperties
from qiskit.providers.models import PulseDefaults
from qiskit.providers.models import PulseDefaults # pylint: disable=no-name-in-module
from qiskit.providers.models.pulsedefaults import Command
from qiskit.providers.options import Options
from qiskit.pulse import Schedule, ScheduleBlock
Expand Down Expand Up @@ -544,7 +544,7 @@ def __init__(
**kwargs,
)

self._defaults = PulseDefaults.from_dict(
self._defaults = PulseDefaults.from_dict( # pylint: disable=no-member
{
"qubit_freq_est": [qubit_frequency / 1e9],
"meas_freq_est": [0],
Expand Down
1 change: 1 addition & 0 deletions qiskit_experiments/test/t2hahn_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ def run(self, dag: DAGCircuit):

if node.name == "delay":
q0 = qubit_indices[node.qargs[0]]
duration = 0
if self.qubit_frequencies[q0] is None:
continue
if node.op.unit == "dt":
Expand Down
4 changes: 2 additions & 2 deletions requirements-dev.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Linters
black~=22.0
pylint~=3.0.2
astroid~=3.0.1 # Must be kept aligned to what pylint wants
pylint~=3.3.1
astroid~=3.3.4 # Must be kept aligned to what pylint wants

# Test runner tools
coverage>=5.5
Expand Down
3 changes: 1 addition & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@
"Operating System :: MacOS",
"Operating System :: POSIX :: Linux",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
Expand All @@ -63,7 +62,7 @@
install_requires=REQUIREMENTS,
extras_require={"extras": EXTRAS},
include_package_data=True,
python_requires=">=3.8",
python_requires=">=3.9",
project_urls={
"Bug Tracker": "https://github.com/Qiskit-Community/qiskit-experiments/issues",
"Documentation": "https://qiskit-community.github.io/qiskit-experiments",
Expand Down
13 changes: 12 additions & 1 deletion test/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,18 @@ def setUpClass(cls):
# ``QiskitTestCase`` sets all warnings to be treated as an error by
# default.
# pylint: disable=invalid-name
allow_deprecationwarning_message = []
allow_deprecationwarning_message = [
".*qiskit.providers.models.backendconfiguration.GateConfig.*",
".*qiskit.qobj.pulse_qobj.PulseLibraryItem.*",
".*qiskit.providers.models.backendconfiguration.UchannelLO.*",
".*qiskit.providers.models.backendconfiguration.PulseBackendConfiguration.*",
".*qiskit.qobj.pulse_qobj.PulseQobjInstruction.*",
".*qiskit.providers.models.backendconfiguration.QasmBackendConfiguration.*",
".*qiskit.qobj.common.QobjDictField.*",
".*qiskit.providers.models.backendproperties.BackendProperties.*",
".*qiskit.providers.fake_provider.fake_backend.FakeBackend.*",
".*qiskit.providers.backend.BackendV1.*",
]
for msg in allow_deprecationwarning_message:
warnings.filterwarnings("default", category=DeprecationWarning, message=msg)

Expand Down
2 changes: 1 addition & 1 deletion test/database_service/test_fake_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ def test_creation(self):

def test_query_for_single(self):
"""Test FakeService methods experiment and analysis_result"""
for query_method, reference_dict, in zip(
for (query_method, reference_dict,) in zip(
[self.service.experiment, self.service.analysis_result], [self.expdict, self.resdict]
):
for id_value in range(len(reference_dict)):
Expand Down
2 changes: 1 addition & 1 deletion test/framework/test_warnings.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def test_warn_sklearn(self):
disallowed_imports = {"sklearn"}
old_import = builtins.__import__
def guarded_import(name, *args, **kwargs):
if name in disallowed_imports:
if name == "sklearn" or name.startswith("sklearn."):
raise import_error(f"Import of {name} not allowed!")
return old_import(name, *args, **kwargs)
builtins.__import__ = guarded_import
Expand Down
10 changes: 5 additions & 5 deletions test/library/calibration/test_fine_amplitude.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,11 +139,11 @@ def test_xp(self):
amp_cal = FineXAmplitude([0])
circs = amp_cal.circuits()

self.assertTrue(circs[0].data[0][0].name == "measure")
self.assertTrue(circs[1].data[0][0].name == "x")
self.assertTrue(circs[0].data[0].operation.name == "measure")
self.assertTrue(circs[1].data[0].operation.name == "x")

for idx, circ in enumerate(circs[2:]):
self.assertTrue(circ.data[0][0].name == "sx")
self.assertTrue(circ.data[0].operation.name == "sx")
self.assertEqual(circ.count_ops().get("x", 0), idx + 1)

def test_x90p(self):
Expand Down Expand Up @@ -204,8 +204,8 @@ def test_measure_qubits(self, qubits):
fine_amp = FineZXAmplitude(qubits)
for circuit in fine_amp.circuits():
self.assertEqual(circuit.num_qubits, 2)
self.assertEqual(circuit.data[-1][0].name, "measure")
self.assertEqual(circuit.data[-1][1][0], circuit.qregs[0][1])
self.assertEqual(circuit.data[-1].operation.name, "measure")
self.assertEqual(circuit.data[-1].qubits[0], circuit.qregs[0][1])


class TestFineAmplitudeCal(QiskitExperimentsTestCase):
Expand Down
2 changes: 1 addition & 1 deletion test/library/calibration/test_fine_drag.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def test_circuits(self):
drag.backend = FakeArmonkV2()
for circuit in drag.circuits()[1:]:
for idx, name in enumerate(["Drag", "rz", "Drag", "rz"]):
self.assertEqual(circuit.data[idx][0].name, name)
self.assertEqual(circuit.data[idx].operation.name, name)

def test_end_to_end(self):
"""A simple test to check if the experiment will run and fit data."""
Expand Down
4 changes: 2 additions & 2 deletions test/library/calibration/test_rabi.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,8 @@ def test_ef_rabi_circuit(self):
pulse.shift_frequency(-anharm, pulse.DriveChannel(2))

self.assertEqual(circ.calibrations["Rabi"][((2,), (0.5,))], expected)
self.assertEqual(circ.data[0][0].name, "x")
self.assertEqual(circ.data[1][0].name, "Rabi")
self.assertEqual(circ.data[0].operation.name, "x")
self.assertEqual(circ.data[1].operation.name, "Rabi")

def test_experiment_config(self):
"""Test converting to and from config works"""
Expand Down
4 changes: 2 additions & 2 deletions test/library/characterization/test_qubit_spectroscopy.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,8 @@ def test_spectroscopy12_end2end_classified(self):

# Test the circuits
circ = spec.circuits()[0]
self.assertEqual(circ.data[0][0].name, "x")
self.assertEqual(circ.data[1][0].name, "Spec")
self.assertEqual(circ.data[0].operation.name, "x")
self.assertEqual(circ.data[1].operation.name, "Spec")

def test_experiment_config(self):
"""Test converting to and from config works"""
Expand Down
3 changes: 2 additions & 1 deletion test/library/characterization/test_zz_ramsey.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ def compute_probabilities(self, circuits: List[QuantumCircuit]) -> List[Dict[str
freq = (-1 * self.zz_freq) / 2
else:
freq = self.zz_freq / 2
rz, _, _ = next(i for i in circuit.data if i[0].name == "u1")
circdata = next(i for i in circuit.data if i.operation.name == "u1")
rz = circdata.operation
phase = float(rz.params[0])

prob1 = 0.5 - 0.5 * np.cos(2 * np.pi * freq * delay + phase)
Expand Down
8 changes: 4 additions & 4 deletions test/library/randomized_benchmarking/test_interleaved_rb.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,11 +149,11 @@ def test_interleaved_structure(self, interleaved_element, qubits, length):
# clifford
self.assertEqual(c_std[std_idx], c_int[int_idx])
# barrier
self.assertEqual(c_std[std_idx + 1][0].name, "barrier")
self.assertEqual(c_int[std_idx + 1][0].name, "barrier")
self.assertEqual(c_std[std_idx + 1].operation.name, "barrier")
self.assertEqual(c_int[std_idx + 1].operation.name, "barrier")
# for interleaved circuit: interleaved element + barrier
self.assertEqual(c_int[int_idx + 2][0].name, interleaved_element.name)
self.assertEqual(c_int[int_idx + 3][0].name, "barrier")
self.assertEqual(c_int[int_idx + 2].operation.name, interleaved_element.name)
self.assertEqual(c_int[int_idx + 3].operation.name, "barrier")
std_idx += 2
int_idx += 4

Expand Down
2 changes: 2 additions & 0 deletions test/library/tomography/test_process_tomography.py
Original file line number Diff line number Diff line change
Expand Up @@ -547,6 +547,8 @@ def test_qpt_conditional_circuit(self, circuit_clbits):
targets = [4 * i.expand(j) for j in [proj0, proj1] for i in [proj0, proj1]]
elif circuit_clbits == [1, 0]:
targets = [4 * i.expand(j) for j in [proj0, proj1] for i in [proj0, proj1]]
else:
targets = None
num_cond = len(circuit_clbits)
prob_target = 0.5**num_cond
for fitter in FITTERS:
Expand Down

0 comments on commit 02572a3

Please sign in to comment.