From c7a945f0f7f6cd671ffe06be4becb89467b3832d Mon Sep 17 00:00:00 2001 From: meandmytram Date: Mon, 25 Nov 2024 19:26:45 -0500 Subject: [PATCH] enhanced data handling --- examples/decoding/quantum_surface.py | 143 ++++++++++++++++++--------- examples/decoding/quantum_surface.sh | 10 +- 2 files changed, 100 insertions(+), 53 deletions(-) diff --git a/examples/decoding/quantum_surface.py b/examples/decoding/quantum_surface.py index 68132aa6..b6b6b314 100644 --- a/examples/decoding/quantum_surface.py +++ b/examples/decoding/quantum_surface.py @@ -2,6 +2,7 @@ import os import sys +import pickle import logging import argparse import numpy as np @@ -54,6 +55,7 @@ def parse_arguments(): + """Parse command line arguments.""" parser = argparse.ArgumentParser( description="Launch quantum surface code decoding on Compute Canada clusters." ) @@ -78,6 +80,12 @@ def parse_arguments(): required=True, help="The number of experiments to run.", ) + parser.add_argument( + "--error_model", + type=str, + required=True, + help="The error model to use.", + ) parser.add_argument( "--seed", type=int, @@ -87,50 +95,17 @@ def parse_arguments(): return parser.parse_args() -def run_experiment(lattice_size, chi_max, error_rate, num_experiments, seed): - logging.info( - f"Starting {num_experiments} experiments for LATTICE_SIZE={lattice_size}, CHI_MAX={chi_max}, ERROR_RATE={error_rate}, SEED={seed}" - ) - - seed_seq = np.random.SeedSequence(seed) - failures = [] - - for l in tqdm(range(num_experiments)): - new_seed = seed_seq.spawn(1)[0] - rng = np.random.default_rng(new_seed) - random_integer = rng.integers(1, 10**8 + 1) - experiment_seed = random_integer - - try: - failure = run_single_experiment( - lattice_size, chi_max, error_rate, experiment_seed - ) - failures.append(failure) - except Exception as e: - logging.error(f"Experiment {l} failed with error: {str(e)}", exc_info=True) - failures.append(1) - - logging.info( - f"Finished experiment {l} for LATTICE_SIZE={lattice_size}, CHI_MAX={chi_max}, ERROR_RATE={error_rate}, SEED={seed}" - ) - - return failures - - -def run_single_experiment(lattice_size, chi_max, error_rate, seed): +def run_single_experiment(lattice_size, chi_max, error, bias_prob, error_model): + """Run a single experiment.""" rep_code = qec.repetition_code(lattice_size) surface_code = qec.hypergraph_product(rep_code, rep_code) - prob_bias = error_rate - error = generate_pauli_error_string(len(surface_code), error_rate, seed=seed) - error_mps = pauli_to_mps(error) - _, success = decode_css( code=surface_code, - error=error_mps, + error=error, chi_max=chi_max, - bias_type="Depolarising", - bias_prob=prob_bias, + bias_type=error_model, + bias_prob=bias_prob, renormalise=True, silent=True, contraction_strategy="Optimised", @@ -144,29 +119,101 @@ def run_single_experiment(lattice_size, chi_max, error_rate, seed): return 1 -def save_failures_statistics(failures, lattice_size, chi_max, error_rate, seed): - failures_statistics = {} - failures_statistics[(lattice_size, chi_max, error_rate)] = failures - failures_key = ( - f"latticesize{lattice_size}_bonddim{chi_max}_errorrate{error_rate}_seed{seed}" +def generate_errors(lattice_size, error_rate, num_experiments, error_model, seed): + """Generate errors for the experiments.""" + seed_seq = np.random.SeedSequence(seed) + errors = [] + + rep_code = qec.repetition_code(lattice_size) + surface_code = qec.hypergraph_product(rep_code, rep_code) + + for _ in range(num_experiments): + rng = np.random.default_rng(seed_seq.spawn(1)[0]) + random_seed = rng.integers(1, 10**8 + 1) + error = generate_pauli_error_string( + len(surface_code), + error_rate, + seed=random_seed, + error_model=error_model, + ) + errors.append(error) + + return errors + + +def run_experiment( + lattice_size, chi_max, error_rate, num_experiments, error_model, seed +): + """Run the experiment consisting of multiple single experiments.""" + logging.info( + f"Starting {num_experiments} experiments for LATTICE_SIZE={lattice_size}," + f"CHI_MAX={chi_max}, ERROR_RATE={error_rate}, ERROR_MODEL={error_model}, SEED={seed}" ) - np.save(f"{failures_key}.npy", failures) + + failures = [] + errors = generate_errors( + lattice_size, error_rate, num_experiments, error_model, seed + ) + + for l in tqdm(range(num_experiments)): + try: + failure = run_single_experiment( + lattice_size=lattice_size, + chi_max=chi_max, + error=errors[l], + bias_prob=error_rate, + error_model=error_model, + ) + failures.append(failure) + except Exception as e: + logging.error(f"Experiment {l} failed with error: {str(e)}", exc_info=True) + failures.append(1) + + logging.info( + f"Finished experiment {l} for LATTICE_SIZE={lattice_size}, CHI_MAX={chi_max}," + f"ERROR_RATE={error_rate}, ERROR_MODEL={error_model}, SEED={seed}" + ) + + return { + "failures": failures, + "errors": errors, + "lattice_size": lattice_size, + "chi_max": chi_max, + "error_rate": error_rate, + "error_model": error_model, + "seed": seed, + } + + +def save_experiment_data(data, lattice_size, chi_max, error_rate, error_model, seed): + """Save the experiment data.""" + file_key = f"latticesize{lattice_size}_bonddim{chi_max}_errorrate{error_rate}_errormodel{error_model}_seed{seed}.pkl" + with open(file_key, "wb") as pickle_file: + pickle.dump(data, pickle_file) logging.info( - f"Completed experiments for {failures_key} with {np.mean(failures)*100:.2f}% failure rate." + f"Saved experiment data for {file_key} with" + f"{np.mean(data['failures'])*100:.2f}% failure rate." ) def main(): + """Main entry point.""" args = parse_arguments() - failures = run_experiment( + experiment_data = run_experiment( args.lattice_size, args.bond_dim, args.error_rate, args.num_experiments, + args.error_model, args.seed, ) - save_failures_statistics( - failures, args.lattice_size, args.bond_dim, args.error_rate, args.seed + save_experiment_data( + experiment_data, + args.lattice_size, + args.bond_dim, + args.error_rate, + args.error_model, + args.seed, ) diff --git a/examples/decoding/quantum_surface.sh b/examples/decoding/quantum_surface.sh index addf561b..bfa46f28 100644 --- a/examples/decoding/quantum_surface.sh +++ b/examples/decoding/quantum_surface.sh @@ -14,15 +14,15 @@ pip install --no-index --upgrade pip pip install --no-index numpy scipy opt_einsum tqdm qecstruct more_itertools networkx matrex@git+https://github.com/quicophy/matrex # Define arrays of lattice sizes, bond dimensions, and error rates -lattice_sizes=(4 5 6 7) -bond_dims=(4 8 16 32 64 128) +lattice_sizes=(3 5 7 9 11) +bond_dims=(4 8 16 32 64 128 256 512) seeds=(123 124 125 126 127 128 129 130 131 132) # 10 random seeds num_experiments=10 # Per each random seed error_rates=() -start=0.0001 -end=0.1 -num_points=10 +start=0.05 +end=0.15 +num_points=11 step=$(echo "($end - $start) / ($num_points - 1)" | bc -l) for ((i=0; i<$num_points; i++)) do