Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

General update to bring the main branch up to date #1471

Merged
merged 23 commits into from
Sep 30, 2024
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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"]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this leaves an orphaned 3.8 job on the PR but we can ignore than when merging.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

which one? All the tests seem 3.9 or 3.12 (as far as I can tell)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The branch protection rules were expecting a 3.8 test so it didn't show this PR as ready to merge. I've manually fixed them at 3.9 and 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
1 change: 1 addition & 0 deletions qiskit_experiments/framework/backend_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
Since `BackendV1` and `BackendV2` do not share the same interface, this
class unifies data access for various data fields.
"""
# pylint: disable=no-name-in-module
from qiskit.providers.models import PulseBackendConfiguration
wshanks marked this conversation as resolved.
Show resolved Hide resolved
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
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yuck, this makes pylint happy but doesn't look any better to me (since the only use of timing below fails if it is 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
4 changes: 3 additions & 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 All @@ -59,6 +59,8 @@ def guarded_import(name, *args, **kwargs):
proc = subprocess.run(
[sys.executable, "-c", script], check=False, text=True, capture_output=True
)
print(proc.stdout)
print(proc.stderr)
wshanks marked this conversation as resolved.
Show resolved Hide resolved

self.assertTrue(
proc.stdout.startswith("qiskit_experiments imported!"),
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