Repository: Qiskit/qiskit

Issue:
CommutationChecker fails if an operation name is not ascii-encodable.
### Environment

- **Qiskit version**: 1.0.0
- **Python version**:  3.12.1
- **Operating system**:  Linux


### What is happening?

`CommutationChecker` fails if an operation name is not ascii-encodable.

### How can we reproduce the issue?

```python
from math import pi

from qiskit import QuantumCircuit
from qiskit.circuit import CommutationChecker

sub = QuantumCircuit(2, name="non-ascii-name-π")
sub.rxx(pi, 0, 1)

qc = QuantumCircuit(2)
qc.append(sub.to_instruction(), (0, 1))
qc.rxx(pi, 0, 1)

op0 = qc.data[0].operation
qargs0 = qc.data[0].qubits

op1 = qc.data[1].operation
qargs1 = qc.data[1].qubits

cc = CommutationChecker()
cc.commute(op0, qargs0, [], op1, qargs1, [])
```

Fails with:

```
Traceback (most recent call last):
  File "repro.py", line 20, in <module>
    cc.commute(op0, qargs0, [], op1, qargs1, [])
  File ".../python3.12/site-packages/qiskit/circuit/commutation_checker.py", line 92, in commute
    first_op_tuple, second_op_tuple = _order_operations(
                                      ^^^^^^^^^^^^^^^^^^
  File ".../python3.12/site-packages/qiskit/circuit/commutation_checker.py", line 317, in _order_operations
    if _persistent_id(op1.name) < _persistent_id(op2.name)
       ^^^^^^^^^^^^^^^^^^^^^^^^
  File ".../python3.12/site-packages/qiskit/circuit/commutation_checker.py", line 288, in _persistent_id
    return int.from_bytes(bytes(op_name, encoding="ascii"), byteorder="big", signed=True)
                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
UnicodeEncodeError: 'ascii' codec can't encode character '\u03c0' in position 15: ordinal not in range(128)
```

### What should happen?

The reproduction script should not fail.

### Any suggestions?

Changing the encoding of the bytes used to compute the `persistent_id` to e.g. `utf-8` solves the issue.


Discussion:

Resolving patch:
diff --git a/qiskit/circuit/commutation_checker.py b/qiskit/circuit/commutation_checker.py
--- a/qiskit/circuit/commutation_checker.py
+++ b/qiskit/circuit/commutation_checker.py
@@ -313,7 +313,7 @@ def _persistent_id(op_name: str) -> int:
     Return:
         The integer id of the input string.
     """
-    return int.from_bytes(bytes(op_name, encoding="ascii"), byteorder="big", signed=True)
+    return int.from_bytes(bytes(op_name, encoding="utf-8"), byteorder="big", signed=True)
 
 
 def _order_operations(


Test patch:
diff --git a/test/python/circuit/test_commutation_checker.py b/test/python/circuit/test_commutation_checker.py
--- a/test/python/circuit/test_commutation_checker.py
+++ b/test/python/circuit/test_commutation_checker.py
@@ -39,6 +39,7 @@
     Reset,
     LinearFunction,
     SGate,
+    RXXGate,
 )
 from test import QiskitTestCase  # pylint: disable=wrong-import-order
 
@@ -409,6 +410,16 @@ def test_annotated_operations_commute_with_unannotated(self):
         self.assertTrue(scc.commute(op1, [0, 1], [], op3, [1], []))
         self.assertTrue(scc.commute(op2, [1], [], op3, [1], []))
 
+    def test_utf8_gate_names(self):
+        """Check compatibility of non-ascii quantum gate names."""
+        g0 = RXXGate(1.234).to_mutable()
+        g0.name = "すみません"
+
+        g1 = RXXGate(2.234).to_mutable()
+        g1.name = "ok_0"
+
+        self.assertTrue(scc.commute(g0, [0, 1], [], g1, [1, 0], []))
+
     def test_annotated_operations_no_commute(self):
         """Check non-commutativity involving annotated operations."""
         op1 = AnnotatedOperation(XGate(), [InverseModifier(), ControlModifier(1)])