diff --git a/crates/accelerate/src/sparse_pauli_op.rs b/crates/accelerate/src/sparse_pauli_op.rs index 1a85daf036d9..89f033338951 100644 --- a/crates/accelerate/src/sparse_pauli_op.rs +++ b/crates/accelerate/src/sparse_pauli_op.rs @@ -10,6 +10,7 @@ // copyright notice, and modified files need to carry a notice indicating // that they have been altered from the originals. +use ahash::RandomState; use pyo3::exceptions::{PyRuntimeError, PyValueError}; use pyo3::prelude::*; use pyo3::types::PyTuple; @@ -20,6 +21,7 @@ use numpy::prelude::*; use numpy::{PyArray1, PyArray2, PyReadonlyArray1, PyReadonlyArray2, PyUntypedArrayMethods}; use hashbrown::HashMap; +use indexmap::IndexMap; use ndarray::{s, ArrayView1, ArrayView2, Axis}; use num_complex::Complex64; use num_traits::Zero; @@ -298,7 +300,11 @@ impl MatrixCompressedPaulis { /// explicitly stored operations, if there are duplicates. After the summation, any terms that /// have become zero are dropped. pub fn combine(&mut self) { - let mut hash_table = HashMap::<(u64, u64), Complex64>::with_capacity(self.coeffs.len()); + let mut hash_table = + IndexMap::<(u64, u64), Complex64, RandomState>::with_capacity_and_hasher( + self.coeffs.len(), + RandomState::new(), + ); for (key, coeff) in self .x_like .drain(..) diff --git a/releasenotes/notes/spo-to-matrix-determinism-554389d6fc98627c.yaml b/releasenotes/notes/spo-to-matrix-determinism-554389d6fc98627c.yaml new file mode 100644 index 000000000000..61961d492e72 --- /dev/null +++ b/releasenotes/notes/spo-to-matrix-determinism-554389d6fc98627c.yaml @@ -0,0 +1,6 @@ +--- +fixes: + - | + Fixed a per-process based non-determinism in `SparsePauliOp.to_matrix`. The exact order of the + floating-point operations in the summation would previously vary per process, but will now be + identical between different invocations of the same script. See `#13413 `__.