Skip to content

Commit 60bd4f0

Browse files
committed
lint
1 parent 1bf0581 commit 60bd4f0

50 files changed

Lines changed: 574 additions & 878 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

crates/benchmarks/benches/modules/dem_sampler.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,13 @@
2121
//! - **DEM Sampler - Statistics**: Compare statistics-only methods
2222
//! - **DEM Sampler - Scaling**: How different methods scale with DEM size
2323
24+
use std::str::FromStr;
25+
2426
use criterion::{BenchmarkId, Criterion, Throughput, measurement::Measurement};
2527
use pecos_qec::fault_tolerance::dem_builder::{DemSamplerBuilder, ParsedDem};
2628
use pecos_qec::fault_tolerance::propagator::DagFaultAnalyzer;
2729
use pecos_quantum::DagCircuit;
2830
use pecos_rng::PecosRng;
29-
use rand::SeedableRng;
3031
use std::hint::black_box;
3132

3233
pub fn benchmarks<M: Measurement>(c: &mut Criterion<M>) {
@@ -44,7 +45,6 @@ fn create_surface_code_sampler(
4445
// Create a simplified surface code circuit
4546
let num_data = distance * distance;
4647
let num_ancilla = num_data - 1;
47-
let _num_qubits = num_data + num_ancilla;
4848

4949
let mut dag = DagCircuit::new();
5050

@@ -316,10 +316,12 @@ fn bench_parallel_scaling<M: Measurement>(c: &mut Criterion<M>) {
316316

317317
/// Create a synthetic DEM string for benchmarking.
318318
fn create_synthetic_dem(num_mechanisms: usize, num_detectors: usize, prob: f64) -> String {
319+
use std::fmt::Write;
320+
319321
let mut dem = String::new();
320322

321323
for i in 0..num_detectors {
322-
dem.push_str(&format!("detector({i}, 0, 0) D{i}\n"));
324+
writeln!(dem, "detector({i}, 0, 0) D{i}").unwrap();
323325
}
324326

325327
for i in 0..num_mechanisms {
@@ -328,9 +330,9 @@ fn create_synthetic_dem(num_mechanisms: usize, num_detectors: usize, prob: f64)
328330
let d3 = (i + 2) % num_detectors;
329331

330332
match i % 3 {
331-
0 => dem.push_str(&format!("error({prob}) D{d1}\n")),
332-
1 => dem.push_str(&format!("error({prob}) D{d1} D{d2}\n")),
333-
_ => dem.push_str(&format!("error({prob}) D{d1} D{d2} D{d3}\n")),
333+
0 => writeln!(dem, "error({prob}) D{d1}").unwrap(),
334+
1 => writeln!(dem, "error({prob}) D{d1} D{d2}").unwrap(),
335+
_ => writeln!(dem, "error({prob}) D{d1} D{d2} D{d3}").unwrap(),
334336
}
335337
}
336338

crates/pecos-fusion-blossom/src/decoder.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,6 @@ impl FusionBlossomDecoder {
213213
/// .add_edge(1, 2, vec![1], Some(1.0))
214214
/// .build()?;
215215
/// ```
216-
#[must_use]
217216
pub fn builder() -> crate::builder::FusionBlossomBuilder {
218217
crate::builder::FusionBlossomBuilder::new()
219218
}

crates/pecos-ldpc-decoders/src/decoders.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ impl BpOsdDecoder {
5656
/// .osd_method(OsdMethod::Osd0)
5757
/// .build()?;
5858
/// ```
59-
#[must_use]
6059
pub fn builder(pcm: &SparseMatrix) -> crate::builders::BpOsdBuilder<'_> {
6160
crate::builders::BpOsdBuilder::new(pcm)
6261
}
@@ -287,7 +286,6 @@ impl BpLsdDecoder {
287286
/// .lsd_method(OsdMethod::Osd0)
288287
/// .build()?;
289288
/// ```
290-
#[must_use]
291289
pub fn builder(pcm: &SparseMatrix) -> crate::builders::BpLsdBuilder<'_> {
292290
crate::builders::BpLsdBuilder::new(pcm)
293291
}
@@ -565,7 +563,6 @@ pub struct SoftInfoBpDecoder {
565563

566564
impl SoftInfoBpDecoder {
567565
/// Create a builder for configuring a new Soft Information BP decoder
568-
#[must_use]
569566
pub fn builder(pcm: &SparseMatrix) -> crate::builders::SoftInfoBpBuilder<'_> {
570567
crate::builders::SoftInfoBpBuilder::new(pcm)
571568
}
@@ -742,7 +739,6 @@ pub struct FlipDecoder {
742739

743740
impl FlipDecoder {
744741
/// Create a builder for configuring a new Flip decoder
745-
#[must_use]
746742
pub fn builder(pcm: &SparseMatrix) -> crate::builders::FlipBuilder<'_> {
747743
crate::builders::FlipBuilder::new(pcm)
748744
}
@@ -863,7 +859,6 @@ impl UfMethod {
863859

864860
impl UnionFindDecoder {
865861
/// Create a builder for configuring a new Union-Find decoder
866-
#[must_use]
867862
pub fn builder(pcm: &SparseMatrix) -> crate::builders::UnionFindBuilder<'_> {
868863
crate::builders::UnionFindBuilder::new(pcm)
869864
}
@@ -959,7 +954,6 @@ impl BeliefFindDecoder {
959954
///
960955
/// `BeliefFind` combines BP with Union-Find: it first tries BP, and if that
961956
/// fails to converge, it falls back to Union-Find using soft information from BP.
962-
#[must_use]
963957
pub fn builder(pcm: &SparseMatrix) -> crate::builders::BeliefFindBuilder<'_> {
964958
crate::builders::BeliefFindBuilder::new(pcm)
965959
}

crates/pecos-qec/src/fault_tolerance/dem_builder/builder.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ impl<'a> DemBuilder<'a> {
122122
/// # Arguments
123123
///
124124
/// * `order` - List of qubit indices in measurement execution order.
125-
/// `order[i]` is the qubit measured at `TickCircuit` measurement index `i`.
125+
/// `order[i]` is the qubit measured at `TickCircuit` measurement index `i`.
126126
#[must_use]
127127
pub fn with_measurement_order(mut self, order: Vec<usize>) -> Self {
128128
self.measurement_order = Some(order);
@@ -384,7 +384,7 @@ impl<'a> DemBuilder<'a> {
384384
1 => x.clone(), // X
385385
2 => x.xor(z), // Y = X XOR Z
386386
3 => z.clone(), // Z
387-
_ => ErrorMechanism::new(),
387+
_ => unreachable!("Pauli index must be 0-3"),
388388
}
389389
};
390390

@@ -912,7 +912,7 @@ mod tests {
912912
// Test DEPOLARIZE1: p=0.01, n=3
913913
let p1 = per_channel_probability(0.01, 3);
914914
// Should be 1 - (1-0.01)^(1/3) = 0.003344...
915-
assert!((p1 - 0.003344506).abs() < 1e-6);
915+
assert!((p1 - 0.003_344_506).abs() < 1e-6);
916916

917917
// Verify: combining 3 channels gives back ~p
918918
let combined = 1.0 - (1.0 - p1).powi(3);
@@ -921,16 +921,16 @@ mod tests {
921921
// Test DEPOLARIZE2: p=0.02, n=15
922922
let p2 = per_channel_probability(0.02, 15);
923923
// Should be 1 - (1-0.02)^(1/15) = 0.001346...
924-
assert!((p2 - 0.001345941).abs() < 1e-6);
924+
assert!((p2 - 0.001_345_941).abs() < 1e-6);
925925

926926
// Verify: combining 15 channels gives back ~p
927927
let combined2 = 1.0 - (1.0 - p2).powi(15);
928928
assert!((combined2 - 0.02).abs() < 1e-10);
929929

930930
// Edge cases
931-
assert_eq!(per_channel_probability(0.0, 3), 0.0);
932-
assert_eq!(per_channel_probability(1.0, 3), 1.0);
933-
assert_eq!(per_channel_probability(-0.1, 3), 0.0);
931+
assert!((per_channel_probability(0.0, 3) - 0.0).abs() < f64::EPSILON);
932+
assert!((per_channel_probability(1.0, 3) - 1.0).abs() < f64::EPSILON);
933+
assert!((per_channel_probability(-0.1, 3) - 0.0).abs() < f64::EPSILON);
934934

935935
// For small p, should be close to p/n
936936
let small_p = per_channel_probability(0.001, 15);

crates/pecos-qec/src/fault_tolerance/dem_builder/dem_sampler.rs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -595,9 +595,8 @@ impl DemSampler {
595595
num_shots: usize,
596596
rng: &mut R,
597597
) -> SamplingStatistics {
598-
let chunk_size = match self.optimal_chunk_size(num_shots) {
599-
Some(size) => size,
600-
None => return self.sample_statistics_direct(num_shots, rng),
598+
let Some(chunk_size) = self.optimal_chunk_size(num_shots) else {
599+
return self.sample_statistics_direct(num_shots, rng);
601600
};
602601

603602
let mut total_stats = SamplingStatistics::new(num_shots);
@@ -2177,10 +2176,10 @@ mod tests {
21772176

21782177
// Compare geometric to baseline with many shots for statistical significance
21792178
let mut rng1 = SmallRng::seed_from_u64(42);
2180-
let stats1 = sampler.sample_statistics_columnar(100000, &mut rng1);
2179+
let stats1 = sampler.sample_statistics_columnar(100_000, &mut rng1);
21812180

21822181
let mut rng2 = SmallRng::seed_from_u64(42);
2183-
let stats2 = sampler.sample_statistics_geometric(100000, &mut rng2);
2182+
let stats2 = sampler.sample_statistics_geometric(100_000, &mut rng2);
21842183

21852184
// Statistics should be similar
21862185
let rate1 = stats1.syndrome_rate();
@@ -2283,11 +2282,11 @@ mod tests {
22832282

22842283
// Compare parallel to sequential
22852284
let mut rng = SmallRng::seed_from_u64(42);
2286-
let stats_seq = sampler.sample_statistics_geometric(100000, &mut rng);
2285+
let stats_seq = sampler.sample_statistics_geometric(100_000, &mut rng);
22872286

22882287
// Parallel uses different RNG seeds per chunk, so results won't match exactly
22892288
// but should be statistically similar
2290-
let stats_par = sampler.sample_statistics_parallel(100000, 42);
2289+
let stats_par = sampler.sample_statistics_parallel(100_000, 42);
22912290

22922291
let rate_seq = stats_seq.syndrome_rate();
22932292
let rate_par = stats_par.syndrome_rate();
@@ -2415,7 +2414,7 @@ mod tests {
24152414
let sampler = DemSampler::from_mechanisms(mechanisms, 1, 0);
24162415

24172416
// Should still work correctly
2418-
let stats = sampler.sample_statistics(100000, 42);
2417+
let stats = sampler.sample_statistics(100_000, 42);
24192418
let rate = stats.syndrome_rate();
24202419
assert!(
24212420
(rate - 0.0001).abs() < 0.001,

crates/pecos-qec/src/fault_tolerance/dem_builder/equivalence.rs

Lines changed: 73 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@
5353
use pecos_rng::{PecosRng, Rng};
5454
use std::collections::{BTreeMap, BTreeSet};
5555

56+
use std::fmt;
57+
use std::str::FromStr;
58+
5659
use super::types::combine_probabilities;
5760

5861
// ============================================================================
@@ -160,10 +163,10 @@ impl EffectKey {
160163
observables,
161164
}
162165
}
166+
}
163167

164-
/// Formats this key as a string (e.g., "D0 D1 L0").
165-
#[must_use]
166-
pub fn to_string(&self) -> String {
168+
impl fmt::Display for EffectKey {
169+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
167170
let mut parts: Vec<String> = Vec::new();
168171
for &d in &self.detectors {
169172
parts.push(format!("D{d}"));
@@ -172,9 +175,9 @@ impl EffectKey {
172175
parts.push(format!("L{o}"));
173176
}
174177
if parts.is_empty() {
175-
"(empty)".to_string()
178+
write!(f, "(empty)")
176179
} else {
177-
parts.join(" ")
180+
write!(f, "{}", parts.join(" "))
178181
}
179182
}
180183
}
@@ -208,54 +211,12 @@ impl ParsedDem {
208211
/// Parses a DEM from a string.
209212
///
210213
/// Supports both Stim and PECOS DEM formats.
211-
pub fn from_str(dem_str: &str) -> Result<Self, DemParseError> {
212-
let mut mechanisms = Vec::new();
213-
let mut max_det: i32 = -1;
214-
let mut max_obs: i32 = -1;
215-
216-
for line in dem_str.lines() {
217-
let line = line.trim();
218-
219-
// Skip empty lines and comments
220-
if line.is_empty() || line.starts_with('#') {
221-
continue;
222-
}
223-
224-
// Parse error lines
225-
if line.starts_with("error(") {
226-
let mech = Self::parse_error_line(line)?;
227-
228-
// Update max IDs
229-
for comp in &mech.components {
230-
for &d in &comp.detectors {
231-
max_det = max_det.max(d as i32);
232-
}
233-
for &o in &comp.observables {
234-
max_obs = max_obs.max(o as i32);
235-
}
236-
}
237-
238-
mechanisms.push(mech);
239-
}
240-
// Parse detector declarations
241-
else if line.starts_with("detector") {
242-
if let Some(id) = Self::extract_detector_id(line) {
243-
max_det = max_det.max(id as i32);
244-
}
245-
}
246-
// Parse observable declarations
247-
else if line.starts_with("logical_observable")
248-
&& let Some(id) = Self::extract_observable_id(line)
249-
{
250-
max_obs = max_obs.max(id as i32);
251-
}
252-
}
253-
254-
Ok(Self {
255-
mechanisms,
256-
num_detectors: if max_det >= 0 { max_det as u32 + 1 } else { 0 },
257-
num_observables: if max_obs >= 0 { max_obs as u32 + 1 } else { 0 },
258-
})
214+
///
215+
/// # Errors
216+
///
217+
/// Returns `DemParseError` if the string cannot be parsed.
218+
pub fn parse(dem_str: &str) -> Result<Self, DemParseError> {
219+
dem_str.parse()
259220
}
260221

261222
/// Parses a single error line.
@@ -304,13 +265,13 @@ impl ParsedDem {
304265
let mut observables = Vec::new();
305266

306267
for token in s.split_whitespace() {
307-
if token.starts_with('D') {
308-
let id: u32 = token[1..]
268+
if let Some(id_str) = token.strip_prefix('D') {
269+
let id: u32 = id_str
309270
.parse()
310271
.map_err(|_| DemParseError::InvalidDetectorId(token.to_string()))?;
311272
detectors.push(id);
312-
} else if token.starts_with('L') {
313-
let id: u32 = token[1..]
273+
} else if let Some(id_str) = token.strip_prefix('L') {
274+
let id: u32 = id_str
314275
.parse()
315276
.map_err(|_| DemParseError::InvalidObservableId(token.to_string()))?;
316277
observables.push(id);
@@ -473,6 +434,60 @@ impl Default for ParsedDem {
473434
}
474435
}
475436

437+
impl FromStr for ParsedDem {
438+
type Err = DemParseError;
439+
440+
fn from_str(dem_str: &str) -> Result<Self, Self::Err> {
441+
let mut mechanisms = Vec::new();
442+
let mut max_det: i32 = -1;
443+
let mut max_obs: i32 = -1;
444+
445+
for line in dem_str.lines() {
446+
let line = line.trim();
447+
448+
// Skip empty lines and comments
449+
if line.is_empty() || line.starts_with('#') {
450+
continue;
451+
}
452+
453+
// Parse error lines
454+
if line.starts_with("error(") {
455+
let mech = Self::parse_error_line(line)?;
456+
457+
// Update max IDs
458+
for comp in &mech.components {
459+
for &d in &comp.detectors {
460+
max_det = max_det.max(d as i32);
461+
}
462+
for &o in &comp.observables {
463+
max_obs = max_obs.max(o as i32);
464+
}
465+
}
466+
467+
mechanisms.push(mech);
468+
}
469+
// Parse detector declarations
470+
else if line.starts_with("detector") {
471+
if let Some(id) = Self::extract_detector_id(line) {
472+
max_det = max_det.max(id as i32);
473+
}
474+
}
475+
// Parse observable declarations
476+
else if line.starts_with("logical_observable")
477+
&& let Some(id) = Self::extract_observable_id(line)
478+
{
479+
max_obs = max_obs.max(id as i32);
480+
}
481+
}
482+
483+
Ok(Self {
484+
mechanisms,
485+
num_detectors: if max_det >= 0 { max_det as u32 + 1 } else { 0 },
486+
num_observables: if max_obs >= 0 { max_obs as u32 + 1 } else { 0 },
487+
})
488+
}
489+
}
490+
476491
// ============================================================================
477492
// Parse Errors
478493
// ============================================================================
@@ -928,7 +943,7 @@ mod tests {
928943

929944
assert_eq!(dem.mechanisms.len(), 1);
930945
assert!(!dem.mechanisms[0].is_decomposed());
931-
assert_eq!(dem.mechanisms[0].probability, 0.01);
946+
assert!((dem.mechanisms[0].probability - 0.01).abs() < f64::EPSILON);
932947
assert_eq!(dem.mechanisms[0].components[0].detectors, vec![0, 1]);
933948
}
934949

0 commit comments

Comments
 (0)