Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
5 changes: 5 additions & 0 deletions .azure/test-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -165,3 +165,8 @@ jobs:

- bash: image_tests/bin/python -m unittest discover -v test/ipynb
displayName: 'Run image test'
env:
# Needed to suppress a warning in jupyter-core 5.x by eagerly migrating to
# a new internal interface that will be the default in jupyter-core 6.x.
# This variable should become redundant on release of jupyter-core 6.
JUPYTER_PLATFORM_DIRS: 1
41 changes: 17 additions & 24 deletions .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,61 +11,54 @@ jobs:
name: Coverage
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
name: Install Python
with:
python-version: '3.8'

- name: Install Rust toolchain
uses: actions-rs/toolchain@v1
with:
toolchain: stable
override: true
profile: default
components: llvm-tools-preview

- name: Install dependencies
run: |
pip install coveragepy-lcov
cargo install grcov
sudo apt-get install lcov
- name: Download grcov for rust coverage
run: curl -L https://github.com/mozilla/grcov/releases/download/v0.8.11/grcov-x86_64-unknown-linux-gnu.tar.bz2 | tar xj

- name: Build and install qiskit-terra
run: pip install -e .
env:
CARGO_INCREMENTAL: 0
RUSTFLAGS: "-Cinstrument-coverage"
LLVM_PROFILE_FILE: "qiskit-%p-%m.profraw"
SETUPTOOLS_ENABLE_FEATURES: "legacy-editable"

- name: Generate unittest coverage report
run: |
set -e
pip install -r requirements-dev.txt qiskit-aer
stestr run
./grcov . --binary-path ./target/debug/ -s . --llvm --parallel -t lcov --branch --ignore-not-existing --ignore "/*" -o ./rust_unittest.info
mkdir rust_lcov
mv ./rust_unittest.info rust_lcov/.
rm *profraw
# We set the --source-dir to '.' because we want all paths to appear relative to the repo
# root (we need to combine them with the Python ones), but we only care about `grcov`
# keeping the `src/*` files; we don't care about coverage in dependencies.
grcov . --binary-path target/debug/ --source-dir . --output-type lcov --output-path rust.info --llvm --branch --parallel --keep-only 'src/*'
env:
QISKIT_TEST_CAPTURE_STREAMS: 1
QISKIT_PARALLEL: FALSE
PYTHON: "coverage3 run --source qiskit --parallel-mode"
- name: Generate parallel_map test
run: |
set -e
coverage3 run --source qiskit --parallel-mode ./tools/verify_parallel_map.py
./grcov . --binary-path ./target/debug/ -s . --llvm --parallel -t lcov --branch --ignore-not-existing --ignore "/*" -o ./rust_parallel_map.info
mv rust_lcov/rust_unittest.info .
env:
QISKIT_TEST_CAPTURE_STREAMS: 1
QISKIT_PARALLEL: FALSE
PYTHON: "coverage3 run --source qiskit --parallel-mode"
PYTHON: "coverage run --source qiskit --parallel-mode"

- name: Convert to lcov and combine data
run: |
set -e
coverage3 combine
coveragepy-lcov --output_file_path python.info
lcov --add-tracefile python.info -a rust_unittest.info -a rust_parallel_map.info -o combined.info
lcov --remove combined.info "target/*" -o coveralls.info
coverage combine
coverage lcov -o python.info
lcov --add-tracefile python.info --add-tracefile rust.info --output-file coveralls.info

- name: Coveralls
uses: coverallsapp/github-action@master
with:
Expand Down
21 changes: 0 additions & 21 deletions constraints.txt
Original file line number Diff line number Diff line change
@@ -1,24 +1,3 @@
# jsonschema pinning needed due nbformat==5.1.3 using deprecated behaviour in
# 4.0+. The pin can be removed after nbformat is updated.
jsonschema==3.2.0

# pyparsing restrictions are needed because pyparsing 3.0.0 and 3.0.1 break
# matplotlib's mathtex extensions. At the time of writing (2021-10-25), the
# docs build is pinned to matplotlib<3.4 (current) because of deprecations, so
# as we won't get matplotlib upgrades by default, this constraint likely can't
# be removed until we can unpin matplotlib.
pyparsing<3.0.0

# Jinja2 3.1.0 is incompatible with sphinx and/or jupyter until they are updated
# to work with the new jinja version (the jinja maintainers aren't going to
# fix things) pin to the previous working version.
jinja2==3.0.3

# jupyter-core 5.0.0 started emitting deprecation warnings with ipywidgets via
# a seaborn import. This pin can be removed when compatibility with those
# packages is fixed
jupyter-core==4.11.2

# ipywidgets 8.0.3 started emitting deprecation warnings via a seaborn import.
# This pin can be removed when compatibility with those packages is fixed.
ipywidgets<8.0.3
11 changes: 11 additions & 0 deletions qiskit/algorithms/optimizers/snobfit.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from typing import Any, Dict, Optional, Callable, Tuple, List

import numpy as np
from qiskit.exceptions import QiskitError
from qiskit.utils import optionals as _optionals
from .optimizer import Optimizer, OptimizerSupportLevel, OptimizerResult, POINT

Expand Down Expand Up @@ -50,7 +51,17 @@ def __init__(

Raises:
MissingOptionalLibraryError: scikit-quant or SQSnobFit not installed
QiskitError: If NumPy 1.24.0 or above is installed.
See https://github.com/scikit-quant/scikit-quant/issues/24 for more details.
"""
# check version
version = tuple(map(int, np.__version__.split(".")))
if version >= (1, 24, 0):
raise QiskitError(
"SnobFit is incompatible with NumPy 1.24.0 or above, please "
"install a previous version. See also scikit-quant/scikit-quant#24."
)

super().__init__()
self._maxiter = maxiter
self._maxfail = maxfail
Expand Down
6 changes: 4 additions & 2 deletions qiskit/circuit/instruction.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,11 +131,13 @@ def __eq__(self, other):
pass

try:
if numpy.shape(self_param) == numpy.shape(other_param) and numpy.allclose(
self_asarray = numpy.asarray(self_param)
other_asarray = numpy.asarray(other_param)
if numpy.shape(self_asarray) == numpy.shape(other_asarray) and numpy.allclose(
self_param, other_param, atol=_CUTOFF_PRECISION, rtol=0
):
continue
except TypeError:
except (ValueError, TypeError):
pass

try:
Expand Down
12 changes: 11 additions & 1 deletion qiskit/quantum_info/operators/channel/kraus.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,12 @@ def __init__(self, data, input_dims=None, output_dims=None):
# If the input is a list or tuple we assume it is a list of Kraus
# matrices, if it is a numpy array we assume that it is a single Kraus
# operator
# TODO properly handle array construction from ragged data (like tuple(np.ndarray, None))
# and document these accepted input cases. See also Qiskit/qiskit-terra#9307.
if isinstance(data, (list, tuple, np.ndarray)):
# Check if it is a single unitary matrix A for channel:
# E(rho) = A * rho * A^\dagger
if isinstance(data, np.ndarray) or np.array(data).ndim == 2:
if _is_matrix(data):
# Convert single Kraus op to general Kraus pair
kraus = ([np.asarray(data, dtype=complex)], None)
shape = kraus[0][0].shape
Expand Down Expand Up @@ -320,5 +322,13 @@ def _multiply(self, other):
return ret


def _is_matrix(data):
# return True if data is a 2-d array/tuple/list
if not isinstance(data, np.ndarray):
data = np.array(data, dtype=object)

return data.ndim == 2


# Update docstrings for API docs
generate_apidocs(Kraus)
10 changes: 5 additions & 5 deletions qiskit/test/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,13 +223,13 @@ def setUpClass(cls):
r"The QuantumCircuit.cu.",
r"The CXDirection pass has been deprecated",
r"The pauli_basis function with PauliTable.*",
# TODO: remove the following ignore after seaborn 0.12.0 releases
r"distutils Version classes are deprecated. Use packaging\.version",
# Internal deprecation warning emitted by jupyter client when
# calling nbconvert in python 3.10
r"There is no current event loop",
# Caused by internal scikit-learn scipy usage
r"The 'sym_pos' keyword is deprecated and should be replaced by using",
# jupyter_client 7.4.8 uses deprecated shims in pyzmq that raise warnings with pyzmq 25.
# These are due to be fixed by jupyter_client 8, see:
# - https://github.com/jupyter/jupyter_client/issues/913
# - https://github.com/jupyter/jupyter_client/pull/842
r"zmq\.eventloop\.ioloop is deprecated in pyzmq .*",
]
for msg in allow_DeprecationWarning_message:
warnings.filterwarnings("default", category=DeprecationWarning, message=msg)
Expand Down
19 changes: 2 additions & 17 deletions qiskit/utils/classtools.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,6 @@
_MAGIC_STATICMETHODS = {"__new__"}
_MAGIC_CLASSMETHODS = {"__init_subclass__", "__prepare__"}

# `type` itself has several methods (mostly dunders). When we are wrapping those names, we need to
# make sure that we don't interfere with `type.__getattribute__`'s handling that circumvents the
# normal inheritance rules when appropriate.
_TYPE_METHODS = set(dir(type))


class _lift_to_method: # pylint: disable=invalid-name
"""A decorator that ensures that an input callable object implements ``__get__``. It is
Expand Down Expand Up @@ -146,16 +141,6 @@ def wrap_method(cls: Type, name: str, *, before: Callable = None, after: Callabl
# The best time to apply decorators to methods is before they are bound (e.g. by using function
# decorators during the class definition), but if we're making a class decorator, we can't do
# that. We need the actual definition of the method, so we have to dodge the normal output of
# `type.__getattribute__`, which evalutes descriptors if it finds them, unless the name we're
# looking for is defined on `type` itself. In that case, we need the attribute getter to
# correctly return the underlying object, not the one that `type` defines for its own purposes.
attribute_getter = type.__getattribute__ if name in _TYPE_METHODS else object.__getattribute__
for cls_ in inspect.getmro(cls):
try:
method = attribute_getter(cls_, name)
break
except AttributeError:
pass
else:
raise ValueError(f"Method '{name}' is not defined for class '{cls.__name__}'")
# `type.__getattribute__`, which evalutes descriptors if it finds them.
method = inspect.getattr_static(cls, name)
setattr(cls, name, _WrappedMethod(method, before, after))
11 changes: 11 additions & 0 deletions releasenotes/notes/wrap-method-311-147d254d4b40e805.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
fixes:
- |
Fixed handling of some ``classmethod``s by
:func:`~qiskit.utils.wrap_method` in Python 3.11. Previously, in Python
3.11, ``wrap_method`` would wrap the unbounded function associated with the
``classmethod`` and then fail when invoked because the class object usually
bound to the ``classmethod`` was not passed to the function. Starting in
Python 3.11.1, this issue affected :class:`~qiskit.test.QiskitTestCase`,
preventing it from being imported by other test code. Fixed `#9291
<https://github.com/Qiskit/qiskit-terra/issues/9291>`__.
2 changes: 1 addition & 1 deletion requirements-dev.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
coverage>=4.4.0
coverage>=4.4.0,<7.0
hypothesis>=4.24.3
python-constraint>=1.4
ipython<7.22.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

from ddt import ddt, data, unpack

import numpy
from qiskit import BasicAer
from qiskit.circuit.library import RealAmplitudes
from qiskit.utils import QuantumInstance, algorithm_globals
Expand Down Expand Up @@ -63,6 +64,10 @@ def test_bobyqa(self):
except MissingOptionalLibraryError as ex:
self.skipTest(str(ex))

@unittest.skipIf(
tuple(map(int, numpy.__version__.split("."))) >= (1, 24, 0),
"scikit's SnobFit currently incompatible with NumPy 1.24.0.",
)
def test_snobfit(self):
"""SNOBFIT optimizer test."""
try:
Expand All @@ -71,6 +76,10 @@ def test_snobfit(self):
except MissingOptionalLibraryError as ex:
self.skipTest(str(ex))

@unittest.skipIf(
tuple(map(int, numpy.__version__.split("."))) >= (1, 24, 0),
"scikit's SnobFit currently incompatible with NumPy 1.24.0.",
)
@data((None,), ([(-1, 1), (None, None)],))
@unpack
def test_snobfit_missing_bounds(self, bounds):
Expand Down
2 changes: 1 addition & 1 deletion test/python/test_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,6 @@ def test_triu_to_dense(self):
m = np.random.randint(-100, 100, size=(n, n))
symm = (m + m.T) / 2

triu = np.array([[symm[i, j] for i in range(j, n)] for j in range(n)])
triu = [[symm[i, j] for i in range(j, n)] for j in range(n)]

self.assertTrue(np.array_equal(symm, triu_to_dense(triu)))
2 changes: 1 addition & 1 deletion test/python/utils/test_classtools.py
Original file line number Diff line number Diff line change
Expand Up @@ -529,5 +529,5 @@ def test_raises_on_invalid_name(self):
class Dummy:
pass

with self.assertRaisesRegex(ValueError, "Method 'bad' is not defined for class 'Dummy'"):
with self.assertRaisesRegex(AttributeError, "bad"):
wrap_method(Dummy, "bad", before=lambda self: None)