quantumlib / Stim

A fast stabilizer circuit library.
Apache License 2.0
351 stars 102 forks source link

add more interesting identity operations #855

Open m-mcewen opened 6 days ago

m-mcewen commented 6 days ago

Now that we have tags, adding additional identity operations that might be useful for expressiveness:

II a two qubit identity gate would be useful for cases where we would like stim to check the targets are 2Q gate formatted (ie coming in pairs) but do not want the simulator do do anything. Example use cases would be implementing 2Q non-Clifford gates like the leakage iSWAP gate as II[LiSWAP] 1 2 3 4

I_ERROR a single qubit identity error gate would be useful for cases where we want to add an error instruction that we don't want stim to handle. This would have have stim.GateData('I_ERROR').is_noisy_gate() -> True, and therefore could be easily discovered or stripped from the circuit. It might also be good to propagate this to the DEM as an empty term (or maybe a term with 0 probability?)

II_ERROR would combine these two cases.

Strilanc commented 6 days ago

For now I want to leave these out since you can add these distinctions purely in the tag. What key advantage does II_ERROR[tag] have over I[II_ERROR,tag]?

m-mcewen commented 6 days ago

Basically just code complexity and readability:

I'm doing the I[gate, tag] thing at the moment, and previously easy things like if gd.is_noisy_gate now require a whole tags parser and defining a format internal to the tag (e.g. comma separated + gee-i-hope-no-one-misuses-this). Same with II, I have to parse the tag and then implement the pair-wise check myself inside the hotloop.

To me, basic characteristics of the operation (like the stuff that currently lives in gatedata, is_noisy, is_measurement, is_2q_gate) and the kinds of things I want to add in tags (errors, times, generally hw-specifics) are different levels of relevant-to-stim. The second stuff is not relevant to stim at all, but the first stuff is. I use gatedata a lot, and now using it is getting more complicated bc its information is split between gate data and tags.

As a related note, using tags efficiently is definitely easier when you have each instruction have one tag thing that it's doing rather than multiple, eg I'm doing I[one thing] \n I[another thing] instead of I[one_thing, another_thing] wherever I can, and this is currently my largest exception to that pattern.