Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
caf2fe2
Added GateTypes for CrosstalkPayload and introduced the corresponding…
PabloAndresCQ Oct 29, 2025
c72fac0
Exposed CrosstalkPayload gates through the message_builder interface
PabloAndresCQ Oct 30, 2025
0b69bcb
Only apply crosstalk to already allocated qubits
PabloAndresCQ Oct 30, 2025
e31ae8e
Add validation checking for crosstalk with_average
PabloAndresCQ Nov 1, 2025
08980ab
Commented out test for deprecated channel
PabloAndresCQ Nov 1, 2025
a94fb9c
Added the ability to provide a crosstalk model for the transition pro…
PabloAndresCQ Nov 10, 2025
0e82356
CrosstalkPayload ops no longer carry a strength_factor parameter
PabloAndresCQ Nov 10, 2025
bc76453
Introduced the ability to react to crosstalk-induced measurement outc…
PabloAndresCQ Nov 10, 2025
0684c15
Using GateType in measured_qubits to keep track of the cause of the m…
PabloAndresCQ Nov 10, 2025
7e9a2ab
Only one crosstalk_model shared by global and local. Added missing ke…
PabloAndresCQ Nov 10, 2025
a02757e
Realised there's a wrong assumption. Included TODO comments on how to…
PabloAndresCQ Nov 10, 2025
be08892
Changes from Jake: GeneralNoiseModel now has a results_builder field …
PabloAndresCQ Nov 12, 2025
d660937
Updated some comments answering some questions Jake had left
PabloAndresCQ Nov 12, 2025
be33508
More reasonable default for crosstalk model: trivial transitions 0->0…
PabloAndresCQ Nov 12, 2025
6b84c70
Supporting p_meas_crosstalk parameter for backwards compatibility
PabloAndresCQ Nov 13, 2025
56c48e3
Run cargo fmt --all
PabloAndresCQ Nov 13, 2025
dfbc1c6
Clippy has opinions
PabloAndresCQ Nov 13, 2025
0855b4d
Cleanup and updated test_meas_crosstalk
PabloAndresCQ Nov 13, 2025
f36cd16
Rolled back an unnecessary change
PabloAndresCQ Nov 13, 2025
d403035
fix: Idle gate id typo in gate_type test
PabloAndresCQ Nov 13, 2025
c98a3ca
Now handling the case where Measure or MeasureLeaked are in noiseless…
PabloAndresCQ Nov 13, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 36 additions & 1 deletion crates/pecos-core/src/gate_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ pub enum GateType {
Prep = 134,
// PnZ
Idle = 200,
MeasCrosstalkGlobalPayload = 218,
MeasCrosstalkLocalPayload = 219,
}

impl From<u8> for GateType {
Expand All @@ -107,6 +109,8 @@ impl From<u8> for GateType {
82 => GateType::RZZ,
104 => GateType::Measure,
105 => GateType::MeasureLeaked,
218 => GateType::MeasCrosstalkGlobalPayload,
219 => GateType::MeasCrosstalkLocalPayload,
134 => GateType::Prep,
200 => GateType::Idle,
_ => panic!("Invalid gate type ID: {value}"),
Expand Down Expand Up @@ -138,6 +142,8 @@ impl GateType {
| GateType::SZZdg
| GateType::Measure
| GateType::MeasureLeaked
| GateType::MeasCrosstalkGlobalPayload
| GateType::MeasCrosstalkLocalPayload
| GateType::Prep => 0,

// Gates with one parameter
Expand Down Expand Up @@ -178,7 +184,9 @@ impl GateType {
| GateType::Measure
| GateType::MeasureLeaked
| GateType::Prep
| GateType::Idle => 1,
| GateType::Idle
| GateType::MeasCrosstalkGlobalPayload
| GateType::MeasCrosstalkLocalPayload => 1,

// Two-qubit gates
GateType::CX | GateType::SZZ | GateType::SZZdg | GateType::RZZ => 2,
Expand All @@ -202,6 +210,15 @@ impl GateType {
pub const fn is_two_qubit(self) -> bool {
self.quantum_arity() == 2
}

/// Returns whether this gate is a crosstalk payload gate
#[must_use]
pub const fn is_crosstalk_payload(self) -> bool {
matches!(
self,
GateType::MeasCrosstalkGlobalPayload | GateType::MeasCrosstalkLocalPayload
)
}
}

impl fmt::Display for GateType {
Expand Down Expand Up @@ -229,6 +246,8 @@ impl fmt::Display for GateType {
GateType::MeasureLeaked => write!(f, "MeasureLeaked"),
GateType::Prep => write!(f, "Prep"),
GateType::Idle => write!(f, "Idle"),
GateType::MeasCrosstalkGlobalPayload => write!(f, "MeasCrosstalkGlobalPayload"),
GateType::MeasCrosstalkLocalPayload => write!(f, "MeasCrosstalkLocalPayload"),
}
}
}
Expand All @@ -250,6 +269,9 @@ mod tests {
assert_eq!(GateType::R1XY as u8, 36);
assert_eq!(GateType::Measure as u8, 104);
assert_eq!(GateType::MeasureLeaked as u8, 105);
assert_eq!(GateType::Idle as u8, 200);
assert_eq!(GateType::MeasCrosstalkGlobalPayload as u8, 218);
assert_eq!(GateType::MeasCrosstalkLocalPayload as u8, 219);

assert_eq!(GateType::from(0u8), GateType::I);
assert_eq!(GateType::from(1u8), GateType::X);
Expand All @@ -262,6 +284,9 @@ mod tests {
assert_eq!(GateType::from(36u8), GateType::R1XY);
assert_eq!(GateType::from(104u8), GateType::Measure);
assert_eq!(GateType::from(105u8), GateType::MeasureLeaked);
assert_eq!(GateType::from(200u8), GateType::Idle);
assert_eq!(GateType::from(218u8), GateType::MeasCrosstalkGlobalPayload);
assert_eq!(GateType::from(219u8), GateType::MeasCrosstalkLocalPayload);
}

#[test]
Expand All @@ -277,6 +302,8 @@ mod tests {
assert_eq!(GateType::SZZdg.classical_arity(), 0);
assert_eq!(GateType::Measure.classical_arity(), 0);
assert_eq!(GateType::MeasureLeaked.classical_arity(), 0);
assert_eq!(GateType::MeasCrosstalkGlobalPayload.classical_arity(), 0);
assert_eq!(GateType::MeasCrosstalkLocalPayload.classical_arity(), 0);
assert_eq!(GateType::Prep.classical_arity(), 0);

// Gates with one parameter
Expand Down Expand Up @@ -306,6 +333,8 @@ mod tests {
assert_eq!(GateType::MeasureLeaked.quantum_arity(), 1);
assert_eq!(GateType::Prep.quantum_arity(), 1);
assert_eq!(GateType::Idle.quantum_arity(), 1);
assert_eq!(GateType::MeasCrosstalkGlobalPayload.quantum_arity(), 1);
assert_eq!(GateType::MeasCrosstalkLocalPayload.quantum_arity(), 1);

// Two-qubit gates
assert_eq!(GateType::CX.quantum_arity(), 2);
Expand All @@ -327,6 +356,8 @@ mod tests {
assert!(!GateType::SZZdg.is_parameterized());
assert!(!GateType::Measure.is_parameterized());
assert!(!GateType::MeasureLeaked.is_parameterized());
assert!(!GateType::MeasCrosstalkGlobalPayload.is_parameterized());
assert!(!GateType::MeasCrosstalkLocalPayload.is_parameterized());
assert!(!GateType::Prep.is_parameterized());

// Parameterized gates
Expand All @@ -352,6 +383,8 @@ mod tests {
assert!(GateType::MeasureLeaked.is_single_qubit());
assert!(GateType::Prep.is_single_qubit());
assert!(GateType::Idle.is_single_qubit());
assert!(GateType::MeasCrosstalkGlobalPayload.is_single_qubit());
assert!(GateType::MeasCrosstalkLocalPayload.is_single_qubit());

// Two-qubit gates
assert!(!GateType::CX.is_single_qubit());
Expand All @@ -375,6 +408,8 @@ mod tests {
assert!(!GateType::MeasureLeaked.is_two_qubit());
assert!(!GateType::Prep.is_two_qubit());
assert!(!GateType::Idle.is_two_qubit());
assert!(!GateType::MeasCrosstalkGlobalPayload.is_two_qubit());
assert!(!GateType::MeasCrosstalkLocalPayload.is_two_qubit());

// Two-qubit gates
assert!(GateType::CX.is_two_qubit());
Expand Down
41 changes: 41 additions & 0 deletions crates/pecos-core/src/gates.rs
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,47 @@ impl Gate {
}
}

/// Create a new `MeasCrosstalkGlobalPayload` with the data from runtime.
///
/// # Arguments
///
/// * `qubits` - The qubits that are guaranteed *not* to be affected by the
/// global crosstalk event.
///
/// NOTE: it seems unintuitive to give the complement of the list of victim qubits.
/// It fits better with the previous version of crosstalk, but we might want to
/// refactor this.
///
/// # Returns
///
/// A new `MeasCrosstalkGlobalPayload` gate with the specified parameters
#[must_use]
pub fn meas_crosstalk_global_payload(qubits: &[impl Into<QubitId> + Copy]) -> Self {
Self::new(
GateType::MeasCrosstalkGlobalPayload,
vec![],
qubits.iter().map(|&q| q.into()).collect(),
)
}

/// Create a new `MeasCrosstalkLocalPayload` with the data from runtime.
///
/// # Arguments
///
/// * `qubits` - The qubits that are potential victims of the local crosstalk event.
///
/// # Returns
///
/// A new `MeasCrosstalkLocalPayload` gate with the specified parameters
#[must_use]
pub fn meas_crosstalk_local_payload(qubits: &[impl Into<QubitId> + Copy]) -> Self {
Self::new(
GateType::MeasCrosstalkLocalPayload,
vec![],
qubits.iter().map(|&q| q.into()).collect(),
)
}

/// Returns the number of angle parameters this gate requires
///
/// # Returns
Expand Down
14 changes: 14 additions & 0 deletions crates/pecos-engines/src/byte_message/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,20 @@ impl ByteMessageBuilder {
self
}

/// Add a `MeasCrosstalkGlobalPayload`
pub fn add_meas_crosstalk_global_payload(&mut self, qubits: &[usize]) -> &mut Self {
let gate = Gate::meas_crosstalk_global_payload(qubits);
self.add_gate_command(&gate);
self
}

/// Add a `MeasCrosstalkLocalPayload`
pub fn add_meas_crosstalk_local_payload(&mut self, qubits: &[usize]) -> &mut Self {
let gate = Gate::meas_crosstalk_local_payload(qubits);
self.add_gate_command(&gate);
self
}

/// Add a Prep gate
pub fn add_prep(&mut self, qubits: &[usize]) -> &mut Self {
let gate = Gate::prep(qubits);
Expand Down
2 changes: 1 addition & 1 deletion crates/pecos-engines/src/noise.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ pub use self::noise_rng::NoiseRng;
pub use self::pass_through::{PassThroughNoiseModel, PassThroughNoiseModelBuilder};
pub use self::utils::{NoiseUtils, ProbabilityValidator};
pub use self::weighted_sampler::{
SingleQubitWeightedSampler, TwoQubitWeightedSampler, WeightedSampler,
CrosstalkWeightedSampler, SingleQubitWeightedSampler, TwoQubitWeightedSampler, WeightedSampler,
};

use crate::byte_message::ByteMessage;
Expand Down
5 changes: 4 additions & 1 deletion crates/pecos-engines/src/noise/biased_depolarizing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,10 @@ impl BiasedDepolarizingNoiseModel {
trace!("Applying preparation with possible fault");
self.apply_prep_faults(&mut builder, gate);
}
GateType::Idle | GateType::I => {}
GateType::I
| GateType::Idle
| GateType::MeasCrosstalkLocalPayload
| GateType::MeasCrosstalkGlobalPayload => {}
}
}

Expand Down
7 changes: 5 additions & 2 deletions crates/pecos-engines/src/noise/depolarizing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,8 +162,11 @@ impl DepolarizingNoiseModel {
trace!("Applying preparation with possible fault");
self.apply_prep_faults(&mut builder, gate);
}
GateType::Idle | GateType::I => {
// Idle gates just pass through with no idling noise
GateType::I
| GateType::Idle
| GateType::MeasCrosstalkLocalPayload
| GateType::MeasCrosstalkGlobalPayload => {
// Just pass through with no added noise
// builder.add_quantum_gate(gate);
}
}
Expand Down
Loading
Loading