Skip to content

Conversation

@orpuente-MS
Copy link
Contributor

@orpuente-MS orpuente-MS commented Jan 29, 2026

The main purpose of this PR is to build some infrastructure for writing tests for the CPU simulators. I also added tests for each gate of every simulator verifying known properties of those gates, but I might be missing something.

The easiest way to review this PR is to go to these four new files:

  • full_state_noiseless.rs
  • full_state_noisy.rs
  • clifford_noiseless.rs
  • clifford_noisy.rs

and read the module level docstring at the top of the file. That should have a summary with all the properties being tested for each gate in that file. And if you are interested on how a property is being tested you can jump to the corresponding test.

Missing in this PR: tests for CY and CCX gates, since those are still unimplemented.

}
// The first vector is the zero vector.
// We return `true` iff the second vector is also the zero vector.
None => other.data.iter().all(|b| b.norm() <= TOLERANCE),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you normalize? If so, is this even possible to have all values so small?

.data
.iter()
.zip(other.data.iter())
.find(|(a, _)| a.norm() > TOLERANCE)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider finding the largest by norm. May improve precision.

//! | CZ | CZ|x0⟩ = |x0⟩, CZ(a,b) = CZ(b,a) |
//! | SWAP | Exchanges states, SWAP^2 ~ I |
//! | MZ | MZ ~ MZ MZ (idempotent, does not reset) |
//! | RESET | OP RESET ~ I (resets to |0⟩) |
Copy link
Contributor

@DmitryVasilevsky DmitryVasilevsky Feb 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RESET and RESETZ aren't equivalent to I. They change the state of anything other than 0. However, check_programs_are_eq only check for starting in 0 state. This feels a bit misleading: on one hand, "A equivalent to B" sounds like the two should be the same operators (for example, XX ~ I). One the other hand, the code only checks if they are the same starting from 0 input. One needs to use something like Choi–Jamiołkowski isomorphism to test equivalence.
Having said that, I'm not sure you need to test the full equivalence for these basic tests. You probably need to clarify the definition of equivalence. Or, better yet, don't call it equivalence (even though it is an equivalence relation, just not the one people expect), and say something like "producing the same state starting from zero".

//!
//! `T`, `T_ADJ`, `Rx`, `Ry`, `Rz`, `Rxx`, `Ryy`, `Rzz` (non-Clifford gates)
//!
//! # Gate Properties
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Testing various equivalences starting from 0 state is a very useful addition to test!
One thing feels missing - more basic test. I think for primitive gates we should have tests that check them on all basis vectors. I.e. If we have a one-qubit gate, we check it on |0> and |1>. If we have two-qubit gate, we check it on |00>, |01>, |01>, |11>. If we had a way to set the state before the gate and check the state after the gate, these tests could be as simple as going over a table of each state for each gate.
I'm not sure if we can access or even keep state in different simulators. And this doesn't have to be part of this PR - something to think about when checking basic functionality.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a really good idea. What if we add logic to check_programs_are_eq! to make it so that it runs tests starting from all possible basis vectors instead of just starting from zero? This is not perfect, but it's better than just checking from zero. For example, it would make the test checking that I is equivalent to MResetZ fail, which is good, since that test should be written in another way.

//!
//! # Gate Properties
//!
//! The `~` symbol denotes equivalence up to global phase.
Copy link
Contributor

@DmitryVasilevsky DmitryVasilevsky Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same note on equivalence as in the other file.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants