question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

`PauliList.evolve` raises exception when evolving certain Clifford circuits.

See original GitHub issue

Environment

  • Qiskit Terra version: 0.21.1
  • Python version: 3.9
  • Operating system: MacOS 11.6.7

What is happening?

There is a bug in the BasePauli/PauliList/Pauli classes where the phase vector is sometimes set as dtype uint8 instead of int64 leading to errors when calling the evolve function for circuits containing gates that modify the pauli phase vector.

Whether this happens or not seems to depend on how the Pauli is initialized (sometimes it will be initialized with uint8 phase vector, other times with int64 phase vector).

How can we reproduce the issue?

Minimal example

from qiskit import QuantumCircuit
import qiskit.quantum_info as qi

# Create circuit with gate that modifies Pauli phase
qc = QuantumCircuit(2)
qc.cz(0, 1)

# Generate random Pauli
pauli = qi.random_pauli(2, seed=123)

# Try and evolve
pauli.evolve(qc)

Give the exception:

---------------------------------------------------------------------------
UFuncTypeError                            Traceback (most recent call last)
/var/folders/lp/ftt3j6qs7s90j6h9wszq3jcw0000gn/T/ipykernel_71613/3628800509.py in <module>
      7 pauli = qi.random_pauli(2, seed=123)
      8 #qc = qi.random_clifford(4, seed=123).to_circuit()
----> 9 pauli.evolve(qc)

~/anaconda3/envs/qiskit/lib/python3.9/site-packages/qiskit/quantum_info/operators/symplectic/pauli.py in evolve(self, other, qargs, frame)
    597             other = Pauli(other)
    598 
--> 599         return Pauli(super().evolve(other, qargs=qargs, frame=frame))
    600 
    601     # ---------------------------------------------------------------------

~/anaconda3/envs/qiskit/lib/python3.9/site-packages/qiskit/quantum_info/operators/symplectic/base_pauli.py in evolve(self, other, qargs, frame)
    277         if frame == "s":
    278             return self.copy()._append_circuit(other, qargs=qargs)
--> 279         return self.copy()._append_circuit(other.inverse(), qargs=qargs)
    280 
    281     def _evolve_clifford(self, other, qargs=None, frame="h"):

~/anaconda3/envs/qiskit/lib/python3.9/site-packages/qiskit/quantum_info/operators/symplectic/base_pauli.py in _append_circuit(self, circuit, qargs)
    585             # Get the integer position of the flat register
    586             new_qubits = [qargs[bit_indices[tup]] for tup in instruction.qubits]
--> 587             self._append_circuit(instruction.operation, new_qubits)
    588 
    589         # Since the individual gate evolution functions don't take mod

~/anaconda3/envs/qiskit/lib/python3.9/site-packages/qiskit/quantum_info/operators/symplectic/base_pauli.py in _append_circuit(self, circuit, qargs)
    558             if len(qargs) != 2:
    559                 raise QiskitError("Invalid qubits for 2-qubit gate.")
--> 560             return basis_2q[name](self, qargs[0], qargs[1])
    561 
    562         # If not a Clifford basis gate we try to unroll the gate and

~/anaconda3/envs/qiskit/lib/python3.9/site-packages/qiskit/quantum_info/operators/symplectic/base_pauli.py in _evolve_cz(base_pauli, q1, q2)
    661     base_pauli._z[:, q1] ^= x2
    662     base_pauli._z[:, q2] ^= x1
--> 663     base_pauli._phase += 2 * np.logical_and(x1, x2).T
    664     return base_pauli
    665 

UFuncTypeError: Cannot cast ufunc 'add' output from dtype('int64') to dtype('uint8') with casting rule 'same_kind'

What should happen?

The dtype of the phase vector should always be the same, so that evolution and other methods that attempt to inplace modify the vector don’t cause exceptions for mismatched dtypes.

Any suggestions?

One fix would be to explicitly cast the phase vector when initializing base pauli

Issue Analytics

  • State:closed
  • Created a year ago
  • Reactions:1
  • Comments:6 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
BramDocommented, Aug 2, 2022

I tried : if dtype is None: dtype = np.int64(x.shape[axis])

No errors with this solution, print(pauli.evolve(qc)) shows ZY. So this solution works but casting could also create bug in itself. In any case I will start an PR and run all the tests to be sure.

0reactions
BramDocommented, Sep 1, 2022

As already discussed it is not necessary to modify the _count_y because dtype handling there looks correct for what the function does. The more correct solution is to ensure that whatever’s calling that is passing np.uint8 as the dtype when it’s going to bind the result to a uint8 context, or it manually cast. The caller can be found in the exception handling of the example:

~/anaconda3/envs/qiskit/lib/python3.9/site-packages/qiskit/quantum_info/operators/symplectic/base_pauli.py in _evolve_cz(base_pauli, q1, q2)
    661     base_pauli._z[:, q1] ^= x2
    662     base_pauli._z[:, q2] ^= x1
--> 663     base_pauli._phase += 2 * np.logical_and(x1, x2).T
    664     return base_pauli
    665 

In the example we use an evolve over the phase. This is done by the evolve_cz function. In line 663 the phase vector is set by: base_pauli._phase += 2 * np.logical_and(x1, x2).T

To cast the phase vector to a uint8 we can do: base_pauli._phase += np.uint8(2 * (np.logical_and(x1, x2).T))

Summary No change in the _count_y function but modification of the result of the _evolve_cz function. This works, I got the mathematically correct answer as before and we don’t have to change the phase vector from what it logically should be (u8) to something much wider (i64) with the problem of using to much data all the time.

I’ll be happy to go further with this PR if this is the way to go.

Read more comments on GitHub >

github_iconTop Results From Across the Web

qiskit.quantum_info.PauliList.evolve — Qiskit 0.32.1 documentation
Evolve the Pauli by a Clifford. This returns the Pauli P′=C.P.
Read more >
arXiv:2002.12824v3 [quant-ph] 20 Jul 2020
We call these circuits 'super-Clifford circuits', since the Heisenberg time evolution of these operators corresponds to Clifford evolution ...
Read more >
qiskit-terra Changelog - PyUp.io
Variational Quantum Time Evolution algorithm. (8152) - Add barrier labels and display in 3 circuit drawers (8440) - Adding Cliffords to QuantumCircuits as ......
Read more >
Untitled
Kim clifford actress, Ultra cutting machines, Best treatment blue bottle sting, ... Airborne eo/ir sensors, Athlete evolution, Luc gaidoz champagne, ...
Read more >
Report 03 08 2022_08_31 - qiskit-community/repo-monitor ...
... New Global Optimizer - Differential Evolution from Scipy ... 6b_process_tomography.ipynb legacy tutorial raises exception ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found