Skip to content

Commit 2323304

Browse files
committed
merged with dev
2 parents a224752 + 4cac55b commit 2323304

File tree

12 files changed

+530
-23
lines changed

12 files changed

+530
-23
lines changed

.github/workflows/python-release.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,9 @@ jobs:
208208
- name: Install pecos-rslib
209209
run: pip install ./pecos-rslib-wheel/*.whl
210210

211+
- name: Install build dependencies
212+
run: pip install build
213+
211214
- name: Build quantum-pecos SDist
212215
run: |
213216
cd python/quantum-pecos
@@ -250,6 +253,9 @@ jobs:
250253
- name: Install pecos-rslib
251254
run: pip install ./pecos-rslib-wheel/*.whl
252255

256+
- name: Install build dependencies
257+
run: pip install build
258+
253259
- name: Build quantum-pecos wheel
254260
run: |
255261
cd python/quantum-pecos

Cargo.lock

Lines changed: 0 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/pecos-core/src/gate_type.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ pub enum GateType {
7272
// MZ = 104
7373
Measure = 104,
7474
// MnZ = 105
75+
MeasureLeaked = 105,
7576
// TODO: MPauli instead of the other variants?
7677

7778
// PX = 130
@@ -104,6 +105,7 @@ impl From<u8> for GateType {
104105
58 => GateType::SZZdg,
105106
82 => GateType::RZZ,
106107
104 => GateType::Measure,
108+
105 => GateType::MeasureLeaked,
107109
134 => GateType::Prep,
108110
200 => GateType::Idle,
109111
_ => panic!("Invalid gate type ID: {value}"),
@@ -134,6 +136,7 @@ impl GateType {
134136
| GateType::SZZ
135137
| GateType::SZZdg
136138
| GateType::Measure
139+
| GateType::MeasureLeaked
137140
| GateType::Prep => 0,
138141

139142
// Gates with one parameter
@@ -170,6 +173,7 @@ impl GateType {
170173
| GateType::R1XY
171174
| GateType::U
172175
| GateType::Measure
176+
| GateType::MeasureLeaked
173177
| GateType::Prep
174178
| GateType::Idle => 1,
175179

@@ -217,6 +221,7 @@ impl fmt::Display for GateType {
217221
GateType::SZZdg => write!(f, "SZZdg"),
218222
GateType::RZZ => write!(f, "RZZ"),
219223
GateType::Measure => write!(f, "Measure"),
224+
GateType::MeasureLeaked => write!(f, "MeasureLeaked"),
220225
GateType::Prep => write!(f, "Prep"),
221226
GateType::Idle => write!(f, "Idle"),
222227
}
@@ -239,6 +244,7 @@ mod tests {
239244
assert_eq!(GateType::RZ as u8, 32);
240245
assert_eq!(GateType::R1XY as u8, 36);
241246
assert_eq!(GateType::Measure as u8, 104);
247+
assert_eq!(GateType::MeasureLeaked as u8, 105);
242248

243249
assert_eq!(GateType::from(0u8), GateType::I);
244250
assert_eq!(GateType::from(1u8), GateType::X);
@@ -250,6 +256,7 @@ mod tests {
250256
assert_eq!(GateType::from(32u8), GateType::RZ);
251257
assert_eq!(GateType::from(36u8), GateType::R1XY);
252258
assert_eq!(GateType::from(104u8), GateType::Measure);
259+
assert_eq!(GateType::from(105u8), GateType::MeasureLeaked);
253260
}
254261

255262
#[test]
@@ -264,6 +271,7 @@ mod tests {
264271
assert_eq!(GateType::SZZ.classical_arity(), 0);
265272
assert_eq!(GateType::SZZdg.classical_arity(), 0);
266273
assert_eq!(GateType::Measure.classical_arity(), 0);
274+
assert_eq!(GateType::MeasureLeaked.classical_arity(), 0);
267275
assert_eq!(GateType::Prep.classical_arity(), 0);
268276

269277
// Gates with one parameter
@@ -290,6 +298,7 @@ mod tests {
290298
assert_eq!(GateType::R1XY.quantum_arity(), 1);
291299
assert_eq!(GateType::U.quantum_arity(), 1);
292300
assert_eq!(GateType::Measure.quantum_arity(), 1);
301+
assert_eq!(GateType::MeasureLeaked.quantum_arity(), 1);
293302
assert_eq!(GateType::Prep.quantum_arity(), 1);
294303
assert_eq!(GateType::Idle.quantum_arity(), 1);
295304

@@ -312,6 +321,7 @@ mod tests {
312321
assert!(!GateType::SZZ.is_parameterized());
313322
assert!(!GateType::SZZdg.is_parameterized());
314323
assert!(!GateType::Measure.is_parameterized());
324+
assert!(!GateType::MeasureLeaked.is_parameterized());
315325
assert!(!GateType::Prep.is_parameterized());
316326

317327
// Parameterized gates
@@ -334,6 +344,7 @@ mod tests {
334344
assert!(GateType::R1XY.is_single_qubit());
335345
assert!(GateType::U.is_single_qubit());
336346
assert!(GateType::Measure.is_single_qubit());
347+
assert!(GateType::MeasureLeaked.is_single_qubit());
337348
assert!(GateType::Prep.is_single_qubit());
338349
assert!(GateType::Idle.is_single_qubit());
339350

@@ -356,6 +367,7 @@ mod tests {
356367
assert!(!GateType::R1XY.is_two_qubit());
357368
assert!(!GateType::U.is_two_qubit());
358369
assert!(!GateType::Measure.is_two_qubit());
370+
assert!(!GateType::MeasureLeaked.is_two_qubit());
359371
assert!(!GateType::Prep.is_two_qubit());
360372
assert!(!GateType::Idle.is_two_qubit());
361373

crates/pecos-core/src/gates.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,16 @@ impl Gate {
250250
)
251251
}
252252

253+
/// Create `MeasureLeaked` gate on multiple qubits
254+
#[must_use]
255+
pub fn measure_leaked(qubits: &[impl Into<QubitId> + Copy]) -> Self {
256+
Self::new(
257+
GateType::MeasureLeaked,
258+
vec![],
259+
qubits.iter().map(|&q| q.into()).collect(),
260+
)
261+
}
262+
253263
/// Create Prep gate on multiple qubits
254264
#[must_use]
255265
pub fn prep(qubits: &[impl Into<QubitId> + Copy]) -> Self {

crates/pecos-engines/src/byte_message/builder.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,24 @@ impl ByteMessageBuilder {
449449
self
450450
}
451451

452+
/// Add measure leakage operations for multiple qubits
453+
///
454+
/// This behaves like `add_measurements()` but is intended for measuring qubits
455+
/// that may be in a leaked state. In the future, this will output 0, 1, or 2
456+
/// (where 2 indicates the qubit is leaked).
457+
///
458+
/// # Panics
459+
///
460+
/// Panics if any qubit ID is too large to fit in a u32.
461+
pub fn add_measure_leakages(&mut self, qubit_ids: &[usize]) -> &mut Self {
462+
for &qubit in qubit_ids {
463+
// Add a measure_leaked as a regular gate command
464+
let gate = Gate::measure_leaked(&[qubit]);
465+
self.add_gate_command(&gate);
466+
}
467+
self
468+
}
469+
452470
/// Add a Prep gate
453471
pub fn add_prep(&mut self, qubits: &[usize]) -> &mut Self {
454472
let gate = Gate::prep(qubits);
@@ -732,6 +750,30 @@ mod tests {
732750
}
733751
}
734752

753+
#[test]
754+
fn test_add_measure_leakages() {
755+
// Create a builder
756+
let mut builder = ByteMessageBuilder::new();
757+
let _ = builder.for_quantum_operations();
758+
759+
// Add measure_leakages for multiple qubits
760+
let qubits = vec![0, 1, 2];
761+
builder.add_measure_leakages(&qubits);
762+
763+
// Build the message
764+
let message = builder.build();
765+
766+
// Parse the message
767+
let commands = message.quantum_ops().unwrap();
768+
769+
// Verify the commands
770+
assert_eq!(commands.len(), 3);
771+
for i in 0..3 {
772+
assert_eq!(commands[i].gate_type, GateType::MeasureLeaked);
773+
assert_eq!(commands[i].qubits, vec![QubitId(qubits[i])]);
774+
}
775+
}
776+
735777
#[test]
736778
fn test_batch_structure() {
737779
// Create a builder

crates/pecos-engines/src/noise/biased_depolarizing.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ impl BiasedDepolarizingNoiseModel {
176176
trace!("Applying two-qubit gate with possible fault");
177177
self.apply_tq_faults(&mut builder, gate);
178178
}
179-
GateType::Measure => {
179+
GateType::Measure | GateType::MeasureLeaked => {
180180
trace!("Applying measurement. Will apply bias after engine returns results.");
181181
// we apply biased measurement after the engine
182182
// returns the results, rather than before measurement

crates/pecos-engines/src/noise/depolarizing.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ impl DepolarizingNoiseModel {
150150
GateType::RZ => {
151151
NoiseUtils::add_gate_to_builder(&mut builder, gate);
152152
}
153-
GateType::Measure => {
153+
GateType::Measure | GateType::MeasureLeaked => {
154154
trace!("Applying measurement with possible fault");
155155
self.apply_meas_faults(&mut builder, gate);
156156
NoiseUtils::add_gate_to_builder(&mut builder, gate);

0 commit comments

Comments
 (0)