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

Incompatibility with Numpy 1.25 #10305

Closed
Tracked by #10889
jakelishman opened this issue Jun 19, 2023 · 5 comments · Fixed by #11020
Closed
Tracked by #10889

Incompatibility with Numpy 1.25 #10305

jakelishman opened this issue Jun 19, 2023 · 5 comments · Fixed by #11020
Labels
bug Something isn't working

Comments

@jakelishman
Copy link
Member

Environment

  • Qiskit Terra version: 0.24.1
  • Python version: 3.10
  • Operating system: macOS 13.3.1

What is happening?

The test suite and CI are failing because of new deprecation warnings issued by Numpy 1.25 (removing some unnecessary aliases and deprecating some questionable array-to-scalar conversions that we first encountered in #10120). There also seems to be some sort of behavioural change that's affecting the isometry tests and making them flaky, which is harder to pin down.

How can we reproduce the issue?

Run CI with Numpy 1.25.

What should happen?

No warnings, all tests passing.

Any suggestions?

No response

@jakelishman jakelishman added the bug Something isn't working label Jun 19, 2023
@jakelishman
Copy link
Member Author

I'm not 100% sure what's going on with the isometry tests - the failures seem to have questionably large absolute differences between the expected and resultant matrices. It's plausible that it's related to changes in sin and cos in Numpy 1.25: numpy/numpy#23399, but I'm still looking into it.

@jakelishman
Copy link
Member Author

Here's a reproducer for flaky test behaviour with Numpy 1.25:

import numpy as np
from qiskit.quantum_info import random_unitary, Operator
from qiskit.extensions.quantum_initializer import Isometry

iso = random_unitary(16, seed=278663).data
np.testing.assert_allclose(Operator(Isometry(iso, 0, 0)), Operator(iso))

There are no ancilla qubits, so I think the unitary from the isometry is fully defined and there should be no deviations beyond standard floating-point stuff. Instead, the Operator(Isometry(iso, 0, 0)) part is showing some very nontrivial non-deterministic variance in the off-diagonal elements each time it's called.

@jakelishman
Copy link
Member Author

jakelishman commented Jun 19, 2023

I've narrowed at least one component of this a little bit more. This might not be the only issue, but I do know:

import numpy as np
from numpy import array
from qiskit.extensions.quantum_initializer import UCGate

np.set_printoptions(floatmode="unique")

a1 = [array([[ 0.668014861563423-0.3346551458465917j,  0.277967131510269-0.6037353326489598j],
       [-0.277967131510269-0.6037353326489598j,  0.668014861563423+0.3346551458465917j]]), array([[ 0.2166062838266952+0.8682003952928524j ,  0.4271167766350859+0.12992709700820013j],
       [-0.4271167766350859+0.12992709700820013j,  0.2166062838266952-0.8682003952928524j ]]), array([[-0.2741070097201944 +0.8117613476501147j, -0.01821474636319918+0.5153417164352673j],
       [ 0.01821474636319918+0.5153417164352673j, -0.2741070097201944 -0.8117613476501147j]]), array([[ 0.1623765358315201 +0.9716678872200901j,  0.13410238340678943-0.107293654617689j ],
       [-0.13410238340678943-0.107293654617689j ,  0.1623765358315201 -0.9716678872200901j]]), array([[ 0.8245314897717796  +0.5297803036914427j , -0.014618052150304811-0.19815893809430707j],
       [ 0.014618052150304811-0.19815893809430707j,  0.8245314897717796  -0.5297803036914427j ]]), array([[ 0.7996715550698764 +0.5389276848385285j, -0.26190637639918435-0.0385668838274234j],
       [ 0.26190637639918435-0.0385668838274234j,  0.7996715550698764 -0.5389276848385285j]]), array([[-0.6951654137555511-0.4727347508596223j , -0.4217756893779492+0.33966479166601926j],
       [ 0.4217756893779492+0.33966479166601926j, -0.6951654137555511+0.4727347508596223j ]]), array([[-0.077850612760931  +0.5820993526489561j,  0.06379232106309757+0.8068644034233984j],
       [-0.06379232106309757+0.8068644034233984j, -0.077850612760931  -0.5820993526489561j]])]
uc = UCGate(a1, up_to_diagonal=True)

# As of Numpy 1.25, this call is no longer bit-for-bit deterministic:
uc._get_diagonal()

That call at the end used to produce deterministic output. Now, the various values can differ between calls by an atol of somewhere in the region of 2e-16. This then threads itself through the rest of the functions, occasionally flipping some global phases, and producing different matrices. There's a call to np.linalg.eig in the middle of that above call, which I'm always suspicious of, but the 1.25 changelog doesn't mention anything obvious about how that might be affected.

This doesn't explain to me, however, why the operator for the output isometry differs significantly from the input. Within a single construction, I don't know why minor differences in the FLOPs of the calculation can produce such different output.

github-merge-queue bot pushed a commit to qiskit-community/qiskit-experiments that referenced this issue Jun 19, 2023
### Summary

Numpy released a new version which has caused our tests to fail. See
here for example in Terra:
Qiskit/qiskit#10305

### Details and comments

This PR constrains the version of numpy in the tests. We will need to
Qiskit to align with the new numpy.
github-merge-queue bot pushed a commit to qiskit-community/qiskit-experiments that referenced this issue Jun 19, 2023
### Summary

Numpy released a new version which has caused our tests to fail. See
here for example in Terra:
Qiskit/qiskit#10305

### Details and comments

This PR constrains the version of numpy in the tests. We will need to
Qiskit to align with the new numpy.
@jakelishman
Copy link
Member Author

I don't know if this is the root cause, but I've tracked down a seeming flakiness in the multiply ufunc with complex numbers in Numpy 1.25. On my machine, the file

import sys
import numpy

a = [
    numpy.array([
        [0.37407431362525206 + 0.7981674467868007j, 0.4497329415302707 + 0.1440049168541349j],
        [0.44973294153027066 - 0.14400491685413508j, -0.37407431362525156 + 0.7981674467868008j],
    ])
    for _ in [None] * 2
]
b = 0.7071067811865476 - 0.7071067811865475j

if (a[0] * b)[1, 1] - (a[1] * b)[1, 1]:
    sys.exit(1)

intermittently exits in the failure condition, with the imaginary components differing by 1ULP. I couldn't reproduce that behaviour with Numpy 1.24.3 (or 1.25.0 without AVX2).

I don't really understand how that behaviour could cause a correctness issue in the Isometry decomposition itself - as far as I can tell it shouldn't attempt to recalculate the exact same FLOPs at any other time, so the decomposition should come out maybe differently each time, but correct - but it at least seems to be related.

I've filed the above issue as numpy/numpy#24000. I'm not 100% sure it's a bug in Numpy, but I've chased this about as far as I can think right now.

@jakelishman jakelishman added this to the 0.25.0 milestone Jun 26, 2023
mergify bot pushed a commit to qiskit-community/qiskit-experiments that referenced this issue Jun 29, 2023
### Summary

Numpy released a new version which has caused our tests to fail. See
here for example in Terra:
Qiskit/qiskit#10305

### Details and comments

This PR constrains the version of numpy in the tests. We will need to
Qiskit to align with the new numpy.

(cherry picked from commit a8142f1)
@kdk kdk removed this from the 0.25.0 milestone Jul 19, 2023
@jakelishman
Copy link
Member Author

jakelishman commented Sep 27, 2023

This comment is meant to serve as a documentation point for workarounds for UCGate/multiplixer-gate synthesis problems with NumPy 1.25 and 1.26 on Intel Macs with AVX2 CPU extensions enabled. The comments above this one describe a problem with these versions of NumPy in these conditions, which causes severe problems during our synthesis of multiplexed gates, most commonly encountered in Qiskit by calling UnitaryGate.control().

There are a few options for working around the bug, in order from easiest to most complex:

jakelishman added a commit to jakelishman/qiskit-terra that referenced this issue Oct 16, 2023
This new pass added in Qiskitgh-10634 uses some deprecated Numpy properties
and has some slightly fragile exception-based logic when the required
properties can be directly tested.  This code issues warnings with Numpy
1.25+, which is currently not used by CI due to Qiskitgh-10305.
jakelishman added a commit to jakelishman/qiskit-terra that referenced this issue Oct 16, 2023
This new pass added in Qiskitgh-10634 uses some deprecated Numpy properties
and has some slightly fragile exception-based logic when the required
properties can be directly tested.  This code issues warnings with Numpy
1.25+, which is currently not used by CI due to Qiskitgh-10305.
github-merge-queue bot pushed a commit that referenced this issue Oct 23, 2023
* Fix deprecated Numpy logic in `NormalizeRXAngles`

This new pass added in gh-10634 uses some deprecated Numpy properties
and has some slightly fragile exception-based logic when the required
properties can be directly tested.  This code issues warnings with Numpy
1.25+, which is currently not used by CI due to gh-10305.

* Fix return value
mergify bot pushed a commit that referenced this issue Oct 23, 2023
* Fix deprecated Numpy logic in `NormalizeRXAngles`

This new pass added in gh-10634 uses some deprecated Numpy properties
and has some slightly fragile exception-based logic when the required
properties can be directly tested.  This code issues warnings with Numpy
1.25+, which is currently not used by CI due to gh-10305.

* Fix return value

(cherry picked from commit 6bf90fa)
github-merge-queue bot pushed a commit that referenced this issue Oct 23, 2023
* Fix deprecated Numpy logic in `NormalizeRXAngles`

This new pass added in gh-10634 uses some deprecated Numpy properties
and has some slightly fragile exception-based logic when the required
properties can be directly tested.  This code issues warnings with Numpy
1.25+, which is currently not used by CI due to gh-10305.

* Fix return value

(cherry picked from commit 6bf90fa)

Co-authored-by: Jake Lishman <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants