diff --git a/python/quantum-pecos/src/pecos/__init__.py b/python/quantum-pecos/src/pecos/__init__.py index 63aa000fc..361b04859 100644 --- a/python/quantum-pecos/src/pecos/__init__.py +++ b/python/quantum-pecos/src/pecos/__init__.py @@ -191,9 +191,11 @@ error_models, exceptions, # Exception classes graph, + guppy, # Direct Guppy code generation for QEC - bypasses SLR misc, programs, protocols, + qec, # Pure QEC geometry (surface, color codes) - no SLR dependencies qeccs, quantum, # Quantum types (DagCircuit, Gate, Pauli, etc.) simulators, @@ -326,6 +328,7 @@ "general_noise", "get_guppy_backends", "graph", + "guppy", # Direct Guppy code generation "i8", "i16", "i32", @@ -353,6 +356,7 @@ "programs", "protocols", "qasm_engine", + "qec", # Pure QEC geometry (no SLR dependencies) "qeccs", "qis_engine", "quantum", diff --git a/python/quantum-pecos/src/pecos/guppy/__init__.py b/python/quantum-pecos/src/pecos/guppy/__init__.py new file mode 100644 index 000000000..65a5f6f53 --- /dev/null +++ b/python/quantum-pecos/src/pecos/guppy/__init__.py @@ -0,0 +1,75 @@ +# Copyright 2024 The PECOS Developers +# Licensed under the Apache License, Version 2.0 + +"""Direct Guppy code generation for quantum error correction. + +This module provides code generation utilities for creating Guppy +quantum programs from QEC geometry definitions. It bypasses the SLR +intermediate representation for faster direct Guppy generation. + +Submodules: + surface: Surface code generation + color: Color code generation + transversal: Transversal operations (CNOT for CSS codes) + +Example: + >>> from pecos.guppy import make_surface_code, get_num_qubits + >>> prog = make_surface_code(distance=3, num_rounds=3, basis="Z") + >>> num_qubits = get_num_qubits(3) + >>> result = prog.emulator(num_qubits=num_qubits).stabilizer_sim().run() +""" + +from pecos.guppy.color import ( + generate_color_code_module, + generate_color_code_source, + get_color_code_module, + get_num_qubits_color, + make_color_code, +) +from pecos.guppy.surface import ( + generate_guppy_source, + generate_memory_experiment, + generate_surface_code_module, + get_num_qubits, + get_surface_code_module, + make_surface_code, +) +from pecos.guppy.transversal import ( + CSSCodeType, + get_transversal_num_qubits, + make_color_transversal_cnot, + make_color_transversal_cnot_d3, + make_color_transversal_cnot_with_x, + make_color_transversal_cnot_with_x_d3, + make_css_transversal_cnot, + make_css_transversal_cnot_with_x, + make_surface_transversal_cnot, + make_surface_transversal_cnot_with_x, +) + +__all__ = [ # noqa: RUF022 + # Surface code + "generate_guppy_source", + "generate_memory_experiment", + "generate_surface_code_module", + "get_num_qubits", + "get_surface_code_module", + "make_surface_code", + # Color code + "generate_color_code_module", + "generate_color_code_source", + "get_color_code_module", + "get_num_qubits_color", + "make_color_code", + # Generic CSS transversal operations + "CSSCodeType", + "get_transversal_num_qubits", + "make_css_transversal_cnot", + "make_css_transversal_cnot_with_x", + "make_color_transversal_cnot", + "make_color_transversal_cnot_d3", + "make_color_transversal_cnot_with_x", + "make_color_transversal_cnot_with_x_d3", + "make_surface_transversal_cnot", + "make_surface_transversal_cnot_with_x", +] diff --git a/python/quantum-pecos/src/pecos/guppy/color.py b/python/quantum-pecos/src/pecos/guppy/color.py new file mode 100644 index 000000000..18144fcba --- /dev/null +++ b/python/quantum-pecos/src/pecos/guppy/color.py @@ -0,0 +1,469 @@ +# Copyright 2024 The PECOS Developers +# Licensed under the Apache License, Version 2.0 + +"""Generate Guppy code for 4.8.8 triangular color codes. + +The color code is a CSS code where each stabilizer measures both X and Z +on the same qubit support. Stabilizers are colored red, green, and blue. +""" + +import importlib.util +import sys +import tempfile +from pathlib import Path +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from pecos.qec.color import ColorCode488 + + +# Module state container (avoids global statement) +class _ModuleState: + """Container for module-level mutable state.""" + + temp_dir: Path | None = None + module_cache: dict[int, dict] = {} # noqa: RUF012 + + +_state = _ModuleState() + + +def _get_temp_dir() -> Path: + """Get or create temporary directory for generated code.""" + if _state.temp_dir is None: + _state.temp_dir = Path(tempfile.mkdtemp(prefix="pecos_guppy_color_")) + return _state.temp_dir + + +def generate_color_code_source(code: "ColorCode488") -> str: + """Generate Guppy source code for a color code. + + Args: + code: ColorCode488 instance with geometry + + Returns: + Python/Guppy source code as a string + """ + d = code.distance + num_data = code.num_data + num_stab = code.num_stabilizers + + lines = [ + f'"""4.8.8 Color Code (d={d}) implementation in Guppy.', + "", + "Auto-generated from ColorCode488 geometry.", + "", + f"Data qubits: {num_data}", + f"Stabilizers: {num_stab}", + '"""', + "", + "from guppylang import guppy", + "from guppylang.std.builtins import array, owned, result", + "from guppylang.std.quantum import cx, discard, h, measure, measure_array, qubit, x", + "from guppylang.std.qsystem import measure_and_reset", + "", + "", + ] + + # Generate struct definitions + lines.extend( + [ + "@guppy.struct", + f"class ColorCode_{d}:", + f' """Color code with d={d} ({num_data} data qubits)."""', + "", + f" data: array[qubit, {num_data}]", + "", + "", + "@guppy.struct", + f"class ColorSyndrome_{d}:", + f' """Syndrome for d={d} color code."""', + "", + f" synx: array[bool, {num_stab}]", + f" synz: array[bool, {num_stab}]", + "", + "", + ], + ) + + # Generate X stabilizer measurement functions (H-CNOT-H pattern) + lines.append("# === X Stabilizer Measurements ===") + lines.append("") + + for stab in code.stabilizers: + weight = f"w{stab.weight}, {stab.color}" + lines.extend( + [ + "@guppy", + f"def measure_x_stab_{stab.index}(ax: qubit, data: array[qubit, {num_data}]) -> bool:", + f' """Measure X stabilizer {stab.index} ({weight})."""', + " h(ax)", + ], + ) + lines.extend(f" cx(ax, data[{q}])" for q in stab.qubits) + lines.extend( + [ + " h(ax)", + " return measure_and_reset(ax)", + "", + "", + ], + ) + + # Generate Z stabilizer measurement functions (CNOT pattern) + lines.append("# === Z Stabilizer Measurements ===") + lines.append("") + + for stab in code.stabilizers: + weight = f"w{stab.weight}, {stab.color}" + lines.extend( + [ + "@guppy", + f"def measure_z_stab_{stab.index}(az: qubit, data: array[qubit, {num_data}]) -> bool:", + f' """Measure Z stabilizer {stab.index} ({weight})."""', + ], + ) + lines.extend(f" cx(data[{q}], az)" for q in stab.qubits) + lines.extend( + [ + " return measure_and_reset(az)", + "", + "", + ], + ) + + # Generate syndrome extraction + x_calls = ", ".join(f"sx{s.index}" for s in code.stabilizers) + z_calls = ", ".join(f"sz{s.index}" for s in code.stabilizers) + + lines.extend( + [ + "# === Syndrome Extraction ===", + "", + "@guppy", + "def syndrome_extraction(", + f" code: ColorCode_{d},", + " ax: qubit,", + " az: qubit,", + f") -> ColorSyndrome_{d}:", + ' """Extract full X and Z syndrome."""', + " # Z stabilizers first", + ], + ) + + lines.extend( + f" sz{stab.index} = measure_z_stab_{stab.index}(az, code.data)" + for stab in code.stabilizers + ) + + lines.append("") + lines.append(" # X stabilizers") + + lines.extend( + f" sx{stab.index} = measure_x_stab_{stab.index}(ax, code.data)" + for stab in code.stabilizers + ) + + lines.extend( + [ + "", + f" synx = array({x_calls})", + f" synz = array({z_calls})", + "", + f" return ColorSyndrome_{d}(synx, synz)", + "", + "", + ], + ) + + # Generate initialization functions + lines.extend( + [ + "# === Initialization ===", + "", + "@guppy", + f"def init_z_basis(code: ColorCode_{d}, ax: qubit) -> array[bool, {num_stab}]:", + ' """Initialize logical |0_L> and extract initial X syndrome."""', + " # Qubits start in |0>, which is already a +1 eigenstate of Z stabilizers", + " # Measure X stabilizers to project into code space", + ], + ) + + lines.extend( + f" sx{stab.index} = measure_x_stab_{stab.index}(ax, code.data)" + for stab in code.stabilizers + ) + + lines.extend( + [ + "", + f" return array({x_calls})", + "", + "", + "@guppy", + f"def init_x_basis(code: ColorCode_{d}, az: qubit) -> array[bool, {num_stab}]:", + ' """Initialize logical |+_L> and extract initial Z syndrome."""', + f" for i in range({num_data}):", + " h(code.data[i])", + "", + " # Measure Z stabilizers to project into code space", + ], + ) + + lines.extend( + f" sz{stab.index} = measure_z_stab_{stab.index}(az, code.data)" + for stab in code.stabilizers + ) + + lines.extend( + [ + "", + f" return array({z_calls})", + "", + "", + ], + ) + + # Generate measurement functions + lines.extend( + [ + "# === Measurement ===", + "", + "@guppy", + f"def measure_z_basis(code: ColorCode_{d} @ owned) -> array[bool, {num_data}]:", + ' """Destructively measure in Z basis."""', + " return measure_array(code.data)", + "", + "", + "@guppy", + f"def measure_x_basis(code: ColorCode_{d} @ owned) -> array[bool, {num_data}]:", + ' """Destructively measure in X basis."""', + f" for i in range({num_data}):", + " h(code.data[i])", + " return measure_array(code.data)", + "", + "", + ], + ) + + # Generate logical operators + logical_x_qubits = list(code.get_logical_x()) + logical_z_qubits = list(code.get_logical_z()) + + lines.extend( + [ + "# === Logical Operators ===", + "", + "@guppy", + f"def apply_logical_x(code: ColorCode_{d}) -> None:", + ' """Apply logical X operator."""', + ], + ) + lines.extend(f" x(code.data[{q}])" for q in logical_x_qubits) + + lines.extend( + [ + "", + "", + "@guppy", + f"def apply_logical_z(code: ColorCode_{d}) -> None:", + ' """Apply logical Z operator."""', + " from guppylang.std.quantum import z", + "", + ], + ) + lines.extend(f" z(code.data[{q}])" for q in logical_z_qubits) + + lines.extend( + [ + "", + "", + ], + ) + + # Generate memory experiment factories + lines.extend( + [ + "# === Memory Experiments ===", + "", + "def make_memory_z(num_rounds: int):", + ' """Create Z-basis memory experiment."""', + " from guppylang.std.builtins import comptime", + "", + " @guppy", + " def memory_z() -> None:", + f' """Z-basis memory experiment for d={d} color code."""', + f" data = array(qubit() for _ in range({num_data}))", + " ax = qubit()", + " az = qubit()", + "", + f" code = ColorCode_{d}(data)", + "", + " init_syn = init_z_basis(code, ax)", + ' result("init_synx", init_syn)', + "", + " for _t in range(comptime(num_rounds)):", + " syn = syndrome_extraction(code, ax, az)", + ' result("synx", syn.synx)', + ' result("synz", syn.synz)', + "", + " final = measure_z_basis(code)", + ' result("final", final)', + "", + " discard(ax)", + " discard(az)", + "", + " return memory_z", + "", + "", + "def make_memory_x(num_rounds: int):", + ' """Create X-basis memory experiment."""', + " from guppylang.std.builtins import comptime", + "", + " @guppy", + " def memory_x() -> None:", + f' """X-basis memory experiment for d={d} color code."""', + f" data = array(qubit() for _ in range({num_data}))", + " ax = qubit()", + " az = qubit()", + "", + f" code = ColorCode_{d}(data)", + "", + " init_syn = init_x_basis(code, az)", + ' result("init_synz", init_syn)', + "", + " for _t in range(comptime(num_rounds)):", + " syn = syndrome_extraction(code, ax, az)", + ' result("synx", syn.synx)', + ' result("synz", syn.synz)', + "", + " final = measure_x_basis(code)", + ' result("final", final)', + "", + " discard(ax)", + " discard(az)", + "", + " return memory_x", + "", + ], + ) + + return "\n".join(lines) + + +def _load_color_code_module(d: int) -> dict: + """Load a color code module for distance d, using caching. + + Args: + d: Code distance + + Returns: + Module dictionary with generated functions + """ + if d in _state.module_cache: + return _state.module_cache[d] + + from pecos.qec.color import ColorCode488 # noqa: PLC0415 + + code = ColorCode488.create(distance=d) + source = generate_color_code_source(code) + + # Write to temp file + temp_dir = _get_temp_dir() + temp_file = temp_dir / f"color_d{d}.py" + temp_file.write_text(source) + + # Load module + module_name = f"pecos._generated.color_d{d}" + spec = importlib.util.spec_from_file_location(module_name, temp_file) + if spec is None or spec.loader is None: + msg = f"Failed to create module spec for {temp_file}" + raise RuntimeError(msg) + + module = importlib.util.module_from_spec(spec) + sys.modules[module_name] = module + spec.loader.exec_module(module) + + _state.module_cache[d] = vars(module) + return _state.module_cache[d] + + +def get_color_code_module(d: int) -> dict: + """Get a loaded color code module for distance d. + + Args: + d: Code distance (must be odd >= 3) + + Returns: + Dictionary with module contents and metadata + """ + from pecos.qec.color import ColorCode488 # noqa: PLC0415 + + module = _load_color_code_module(d) + + # Add metadata if not present + if "distance" not in module: + code = ColorCode488.create(distance=d) + module["distance"] = d + module["num_data"] = code.num_data + module["num_stab"] = code.num_stabilizers + + return module + + +def get_num_qubits_color(d: int) -> int: + """Get total number of qubits for a distance-d color code. + + Args: + d: Code distance + + Returns: + Total qubits (num_data + 2 ancilla) + """ + from pecos.qec.color import ColorCode488 # noqa: PLC0415 + + code = ColorCode488.create(distance=d) + return code.num_data + 2 + + +def make_color_code(distance: int, num_rounds: int, basis: str) -> object: + """Create a color code memory experiment. + + Args: + distance: Code distance (must be odd >= 3) + num_rounds: Number of syndrome extraction rounds + basis: 'Z' or 'X' + + Returns: + Guppy function for the experiment + """ + if basis.upper() not in ("Z", "X"): + msg = f"basis must be 'Z' or 'X', got {basis!r}" + raise ValueError(msg) + + module = get_color_code_module(distance) + + factory = ( + module["make_memory_z"] if basis.upper() == "Z" else module["make_memory_x"] + ) + + return factory(num_rounds) + + +def generate_color_code_module(d: int) -> str: + """Generate source code for a distance-d color code module. + + Args: + d: Code distance (must be odd >= 3) + + Returns: + Python/Guppy source code as a string + """ + if d < 3 or d % 2 == 0: + msg = f"Distance must be odd >= 3, got {d}" + raise ValueError(msg) + + from pecos.qec.color import ColorCode488 # noqa: PLC0415 + + code = ColorCode488.create(distance=d) + return generate_color_code_source(code) diff --git a/python/quantum-pecos/src/pecos/guppy/surface.py b/python/quantum-pecos/src/pecos/guppy/surface.py new file mode 100644 index 000000000..7b2bca497 --- /dev/null +++ b/python/quantum-pecos/src/pecos/guppy/surface.py @@ -0,0 +1,499 @@ +# Copyright 2024 The PECOS Developers +# Licensed under the Apache License, Version 2.0 + +"""Generate Guppy code from SurfacePatch geometry. + +This module generates Guppy quantum code from the geometry stored +in a SurfacePatch. The geometry is computed once and stored, then +used to generate code on demand. +""" + +import importlib.util +import sys +import tempfile +from pathlib import Path +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from pecos.qec.surface import SurfacePatch + + +# Module state container (avoids global statement) +class _ModuleState: + """Container for module-level mutable state.""" + + temp_dir: Path | None = None + module_cache: dict[str, object] = {} # noqa: RUF012 + distance_module_cache: dict[int, dict] = {} # noqa: RUF012 + + +_state = _ModuleState() + + +def _get_temp_dir() -> Path: + """Get or create temporary directory for generated code.""" + if _state.temp_dir is None: + _state.temp_dir = Path(tempfile.mkdtemp(prefix="pecos_guppy_")) + return _state.temp_dir + + +def generate_guppy_source(patch: "SurfacePatch") -> str: + """Generate Guppy source code for a surface code patch. + + Args: + patch: SurfacePatch with geometry configuration + + Returns: + Python/Guppy source code as a string + """ + geom = patch.geometry + num_data = geom.num_data + num_x_stab = len(geom.x_stabilizers) + num_z_stab = len(geom.z_stabilizers) + dx, dz = geom.dx, geom.dz + + lines = [ + f'"""Surface code patch (dx={dx}, dz={dz}) implementation in Guppy.', + "", + "Auto-generated from SurfacePatch geometry.", + "", + f"Data qubits: {num_data}", + f"X stabilizers: {num_x_stab}", + f"Z stabilizers: {num_z_stab}", + '"""', + "", + "from guppylang import guppy", + "from guppylang.std.builtins import array, owned, result", + "from guppylang.std.quantum import cx, discard, h, measure, measure_array, qubit, x", + "from guppylang.std.qsystem import measure_and_reset", + "", + "", + ] + + # Generate struct definitions + lines.extend( + [ + "@guppy.struct", + f"class SurfaceCode_{dx}x{dz}:", + f' """Surface code patch with dx={dx}, dz={dz} ({num_data} data qubits)."""', + "", + f" data: array[qubit, {num_data}]", + "", + "", + "@guppy.struct", + f"class Syndrome_{dx}x{dz}:", + f' """Syndrome for dx={dx}, dz={dz} patch."""', + "", + f" synx: array[bool, {num_x_stab}]", + f" synz: array[bool, {num_z_stab}]", + "", + "", + ], + ) + + # Generate X stabilizer measurement functions + lines.append("# === X Stabilizer Measurements ===") + lines.append("") + + for stab in geom.x_stabilizers: + weight = "boundary" if stab.is_boundary else "bulk" + lines.extend( + [ + "@guppy", + f"def measure_x_stab_{stab.index}(ax: qubit, data: array[qubit, {num_data}]) -> bool:", + f' """Measure X stabilizer {stab.index} ({weight}): {list(stab.data_qubits)}."""', + " h(ax)", + ], + ) + lines.extend(f" cx(ax, data[{q}])" for q in stab.data_qubits) + lines.extend( + [ + " h(ax)", + " return measure_and_reset(ax)", + "", + "", + ], + ) + + # Generate Z stabilizer measurement functions + lines.append("# === Z Stabilizer Measurements ===") + lines.append("") + + for stab in geom.z_stabilizers: + weight = "boundary" if stab.is_boundary else "bulk" + lines.extend( + [ + "@guppy", + f"def measure_z_stab_{stab.index}(az: qubit, data: array[qubit, {num_data}]) -> bool:", + f' """Measure Z stabilizer {stab.index} ({weight}): {list(stab.data_qubits)}."""', + ], + ) + lines.extend(f" cx(data[{q}], az)" for q in stab.data_qubits) + lines.extend( + [ + " return measure_and_reset(az)", + "", + "", + ], + ) + + # Generate syndrome extraction + x_calls = ", ".join(f"sx{s.index}" for s in geom.x_stabilizers) + z_calls = ", ".join(f"sz{s.index}" for s in geom.z_stabilizers) + + lines.extend( + [ + "# === Syndrome Extraction ===", + "", + "@guppy", + "def syndrome_extraction(", + f" surf: SurfaceCode_{dx}x{dz},", + " ax: qubit,", + " az: qubit,", + f") -> Syndrome_{dx}x{dz}:", + ' """Extract full syndrome."""', + " # Z stabilizers", + ], + ) + + lines.extend( + f" sz{stab.index} = measure_z_stab_{stab.index}(az, surf.data)" + for stab in geom.z_stabilizers + ) + + lines.append("") + lines.append(" # X stabilizers") + + lines.extend( + f" sx{stab.index} = measure_x_stab_{stab.index}(ax, surf.data)" + for stab in geom.x_stabilizers + ) + + lines.extend( + [ + "", + f" synx = array({x_calls})", + f" synz = array({z_calls})", + "", + f" return Syndrome_{dx}x{dz}(synx, synz)", + "", + "", + ], + ) + + # Generate initialization + lines.extend( + [ + "# === Initialization ===", + "", + "@guppy", + f"def init_z_basis(surf: SurfaceCode_{dx}x{dz}, ax: qubit) -> array[bool, {num_x_stab}]:", + ' """Initialize logical |0_L> and extract initial X syndrome."""', + ], + ) + + lines.extend( + f" sx{stab.index} = measure_x_stab_{stab.index}(ax, surf.data)" + for stab in geom.x_stabilizers + ) + + lines.extend( + [ + "", + f" return array({x_calls})", + "", + "", + "@guppy", + f"def init_x_basis(surf: SurfaceCode_{dx}x{dz}, az: qubit) -> array[bool, {num_z_stab}]:", + ' """Initialize logical |+_L> and extract initial Z syndrome."""', + f" for i in range({num_data}):", + " h(surf.data[i])", + "", + ], + ) + + lines.extend( + f" sz{stab.index} = measure_z_stab_{stab.index}(az, surf.data)" + for stab in geom.z_stabilizers + ) + + lines.extend( + [ + "", + f" return array({z_calls})", + "", + "", + ], + ) + + # Generate measurement + lines.extend( + [ + "# === Measurement ===", + "", + "@guppy", + f"def measure_z_basis(surf: SurfaceCode_{dx}x{dz} @ owned) -> array[bool, {num_data}]:", + ' """Destructively measure in Z basis."""', + " return measure_array(surf.data)", + "", + "", + "@guppy", + f"def measure_x_basis(surf: SurfaceCode_{dx}x{dz} @ owned) -> array[bool, {num_data}]:", + ' """Destructively measure in X basis."""', + f" for i in range({num_data}):", + " h(surf.data[i])", + " return measure_array(surf.data)", + "", + "", + ], + ) + + # Generate logical operators + logical_x_qubits = list(geom.logical_x.data_qubits) if geom.logical_x else [] + logical_z_qubits = list(geom.logical_z.data_qubits) if geom.logical_z else [] + + lines.extend( + [ + "# === Logical Operators ===", + "", + "@guppy", + f"def apply_logical_x(surf: SurfaceCode_{dx}x{dz}) -> None:", + ' """Apply logical X (string along left edge)."""', + ], + ) + lines.extend(f" x(surf.data[{q}])" for q in logical_x_qubits) + + lines.extend( + [ + "", + "", + "@guppy", + f"def apply_logical_z(surf: SurfaceCode_{dx}x{dz}) -> None:", + ' """Apply logical Z (string along top edge)."""', + " from guppylang.std.quantum import z", + "", + ], + ) + lines.extend(f" z(surf.data[{q}])" for q in logical_z_qubits) + + lines.extend( + [ + "", + "", + ], + ) + + # Generate memory experiment factories + lines.extend( + [ + "# === Memory Experiments ===", + "", + "def make_memory_z(num_rounds: int):", + ' """Create Z-basis memory experiment."""', + " from guppylang.std.builtins import comptime", + "", + " @guppy", + " def memory_z() -> None:", + f' """Z-basis memory experiment for dx={dx}, dz={dz}."""', + f" data = array(qubit() for _ in range({num_data}))", + " ax = qubit()", + " az = qubit()", + "", + f" surf = SurfaceCode_{dx}x{dz}(data)", + "", + " init_syn = init_z_basis(surf, ax)", + ' result("init_synx", init_syn)', + "", + " for _t in range(comptime(num_rounds)):", + " syn = syndrome_extraction(surf, ax, az)", + ' result("synx", syn.synx)', + ' result("synz", syn.synz)', + "", + " final = measure_z_basis(surf)", + ' result("final", final)', + "", + " discard(ax)", + " discard(az)", + "", + " return memory_z", + "", + "", + "def make_memory_x(num_rounds: int):", + ' """Create X-basis memory experiment."""', + " from guppylang.std.builtins import comptime", + "", + " @guppy", + " def memory_x() -> None:", + f' """X-basis memory experiment for dx={dx}, dz={dz}."""', + f" data = array(qubit() for _ in range({num_data}))", + " ax = qubit()", + " az = qubit()", + "", + f" surf = SurfaceCode_{dx}x{dz}(data)", + "", + " init_syn = init_x_basis(surf, az)", + ' result("init_synz", init_syn)', + "", + " for _t in range(comptime(num_rounds)):", + " syn = syndrome_extraction(surf, ax, az)", + ' result("synx", syn.synx)', + ' result("synz", syn.synz)', + "", + " final = measure_x_basis(surf)", + ' result("final", final)', + "", + " discard(ax)", + " discard(az)", + "", + " return memory_x", + "", + ], + ) + + return "\n".join(lines) + + +def _load_guppy_module(patch: "SurfacePatch") -> dict: + """Load a Guppy module for a patch, using caching. + + Args: + patch: SurfacePatch with geometry + + Returns: + Module dictionary with generated functions + """ + cache_key = f"{patch.dx}x{patch.dz}" + + if cache_key in _state.module_cache: + return _state.module_cache[cache_key] + + # Generate source + source = generate_guppy_source(patch) + + # Write to temp file (required for Guppy introspection) + temp_dir = _get_temp_dir() + temp_file = temp_dir / f"patch_{cache_key}.py" + temp_file.write_text(source) + + # Load module + module_name = f"pecos._generated.patch_{cache_key}" + spec = importlib.util.spec_from_file_location(module_name, temp_file) + if spec is None or spec.loader is None: + msg = f"Failed to create module spec for {temp_file}" + raise RuntimeError(msg) + + module = importlib.util.module_from_spec(spec) + sys.modules[module_name] = module + spec.loader.exec_module(module) + + _state.module_cache[cache_key] = vars(module) + return _state.module_cache[cache_key] + + +def generate_memory_experiment( + patch: "SurfacePatch", + num_rounds: int, + basis: str, +) -> object: + """Generate a memory experiment for a patch. + + Args: + patch: SurfacePatch configuration + num_rounds: Number of syndrome rounds + basis: 'Z' or 'X' + + Returns: + Guppy function for the experiment + """ + module = _load_guppy_module(patch) + + if basis.upper() == "Z": + factory = module["make_memory_z"] + elif basis.upper() == "X": + factory = module["make_memory_x"] + else: + msg = f"basis must be 'Z' or 'X', got {basis!r}" + raise ValueError(msg) + + return factory(num_rounds) + + +def get_num_qubits(d: int) -> int: + """Get total number of qubits for a distance-d surface code. + + Args: + d: Code distance + + Returns: + Total qubits (d^2 data + 2 ancilla) + """ + return d * d + 2 + + +def generate_surface_code_module(d: int) -> str: + """Generate source code for a distance-d surface code module. + + Args: + d: Code distance (must be odd >= 3) + + Returns: + Python/Guppy source code as a string + """ + if d < 3 or d % 2 == 0: + msg = f"Distance must be odd >= 3, got {d}" + raise ValueError(msg) + + from pecos.qec.surface import SurfacePatch # noqa: PLC0415 + + patch = SurfacePatch.create(distance=d) + return generate_guppy_source(patch) + + +def get_surface_code_module(d: int) -> dict: + """Get a loaded surface code module for distance d. + + Args: + d: Code distance + + Returns: + Dictionary with module contents and metadata + """ + if d in _state.distance_module_cache: + return _state.distance_module_cache[d] + + from pecos.qec.surface import SurfacePatch # noqa: PLC0415 + + patch = SurfacePatch.create(distance=d) + module = _load_guppy_module(patch) + + # Add metadata + module["distance"] = d + module["num_data"] = d * d + module["num_stab"] = (d * d - 1) // 2 + + _state.distance_module_cache[d] = module + return module + + +def make_surface_code(distance: int, num_rounds: int, basis: str) -> object: + """Create a surface code memory experiment. + + Args: + distance: Code distance (must be odd >= 3) + num_rounds: Number of syndrome extraction rounds + basis: 'Z' or 'X' + + Returns: + Compiled Guppy program + """ + if basis.upper() not in ("Z", "X"): + msg = f"basis must be 'Z' or 'X', got {basis!r}" + raise ValueError(msg) + + module = get_surface_code_module(distance) + + factory = ( + module["make_memory_z"] if basis.upper() == "Z" else module["make_memory_x"] + ) + + return factory(num_rounds) diff --git a/python/quantum-pecos/src/pecos/guppy/transversal.py b/python/quantum-pecos/src/pecos/guppy/transversal.py new file mode 100644 index 000000000..6ceaa5a81 --- /dev/null +++ b/python/quantum-pecos/src/pecos/guppy/transversal.py @@ -0,0 +1,920 @@ +# Copyright 2024 The PECOS Developers +# Licensed under the Apache License, Version 2.0 + +"""Generic transversal operations for CSS codes. + +This module provides transversal CNOT generation that works with any CSS code +(surface codes, color codes, etc.) by abstracting over the code-specific details. + +Transversal CNOT between two CSS code blocks applies CX(ctrl[i], tgt[i]) for all +data qubits i. This preserves the CSS structure: X errors on control propagate +to X errors on target, Z errors on target propagate to Z errors on control. +""" + +import importlib.util +import sys +import tempfile +from dataclasses import dataclass +from enum import Enum +from pathlib import Path +from typing import Protocol, runtime_checkable + + +class CSSCodeType(Enum): + """Supported CSS code types.""" + + SURFACE = "surface" + COLOR = "color" + + +@runtime_checkable +class CSSCodeSpec(Protocol): + """Protocol for CSS code specifications.""" + + @property + def num_data(self) -> int: + """Number of data qubits.""" + ... + + @property + def num_x_stabilizers(self) -> int: + """Number of X stabilizers.""" + ... + + @property + def num_z_stabilizers(self) -> int: + """Number of Z stabilizers.""" + ... + + def get_logical_x(self) -> tuple[int, ...]: + """Qubits for logical X operator.""" + ... + + def get_logical_z(self) -> tuple[int, ...]: + """Qubits for logical Z operator.""" + ... + + +@dataclass +class TransversalConfig: + """Configuration for transversal CNOT generation.""" + + code_type: CSSCodeType + distance: int + num_rounds: int = 1 + ctrl_logical_x: bool = False # Apply logical X to control before CNOT + + +# Module state container (avoids global statement) +class _ModuleState: + """Container for module-level mutable state.""" + + temp_dir: Path | None = None + css_transversal_cache: dict[str, dict] = {} # noqa: RUF012 + + +_state = _ModuleState() + + +def _get_temp_dir() -> Path: + """Get or create temporary directory for generated code.""" + if _state.temp_dir is None: + _state.temp_dir = Path(tempfile.mkdtemp(prefix="pecos_guppy_css_trans_")) + return _state.temp_dir + + +def _get_surface_code_info(d: int) -> dict: + """Get surface code parameters.""" + from pecos.qec.surface import SurfacePatch # noqa: PLC0415 + + patch = SurfacePatch.create(distance=d) + geom = patch.geometry + + return { + "num_data": d * d, + "num_x_stab": len(geom.x_stabilizers), + "num_z_stab": len(geom.z_stabilizers), + "x_stabilizers": geom.x_stabilizers, + "z_stabilizers": geom.z_stabilizers, + "logical_x": [i * d for i in range(d)], # Left column + "logical_z": list(range(d)), # Top row + "struct_name": f"SurfaceCode_d{d}", + "syndrome_name": f"SurfaceSyndrome_d{d}", + } + + +def _get_color_code_info(d: int) -> dict: + """Get color code parameters.""" + from pecos.qec.color import ColorCode488 # noqa: PLC0415 + + code = ColorCode488.create(distance=d) + + return { + "num_data": code.num_data, + "num_x_stab": code.num_stabilizers, # Same stabilizers for X and Z + "num_z_stab": code.num_stabilizers, + "stabilizers": code.stabilizers, + "logical_x": list(code.get_logical_x()), + "logical_z": list(code.get_logical_z()), + "struct_name": f"ColorCode_d{d}", + "syndrome_name": f"ColorSyndrome_d{d}", + } + + +def generate_surface_transversal_source(d: int) -> str: + """Generate transversal CNOT source for surface codes.""" + info = _get_surface_code_info(d) + num_data = info["num_data"] + num_x_stab = info["num_x_stab"] + num_z_stab = info["num_z_stab"] + + lines = [ + f'"""Transversal CNOT for distance-{d} surface codes.', + "", + "Auto-generated for logical CNOT between two patches.", + '"""', + "", + "from guppylang import guppy", + "from guppylang.std.builtins import array, owned, result, comptime", + "from guppylang.std.quantum import cx, discard, h, measure, measure_array, qubit, x", + "from guppylang.std.qsystem import measure_and_reset", + "", + "", + ] + + # Struct definitions + lines.extend( + [ + "@guppy.struct", + f"class {info['struct_name']}:", + f' """Surface code patch d={d}."""', + "", + f" data: array[qubit, {num_data}]", + "", + "", + "@guppy.struct", + f"class {info['syndrome_name']}:", + f' """Syndrome for d={d} surface code."""', + "", + f" synx: array[bool, {num_x_stab}]", + f" synz: array[bool, {num_z_stab}]", + "", + "", + ], + ) + + # X stabilizer measurements + lines.append("# === X Stabilizer Measurements ===") + lines.append("") + + for stab in info["x_stabilizers"]: + lines.extend( + [ + "@guppy", + f"def measure_x_stab_{stab.index}(ax: qubit, data: array[qubit, {num_data}]) -> bool:", + f' """Measure X stabilizer {stab.index}."""', + " h(ax)", + ], + ) + lines.extend(f" cx(ax, data[{q}])" for q in stab.data_qubits) + lines.extend( + [ + " h(ax)", + " return measure_and_reset(ax)", + "", + "", + ], + ) + + # Z stabilizer measurements + lines.append("# === Z Stabilizer Measurements ===") + lines.append("") + + for stab in info["z_stabilizers"]: + lines.extend( + [ + "@guppy", + f"def measure_z_stab_{stab.index}(az: qubit, data: array[qubit, {num_data}]) -> bool:", + f' """Measure Z stabilizer {stab.index}."""', + ], + ) + lines.extend(f" cx(data[{q}], az)" for q in stab.data_qubits) + lines.extend( + [ + " return measure_and_reset(az)", + "", + "", + ], + ) + + # Syndrome extraction + x_calls = ", ".join(f"sx{s.index}" for s in info["x_stabilizers"]) + z_calls = ", ".join(f"sz{s.index}" for s in info["z_stabilizers"]) + + lines.extend( + [ + "# === Syndrome Extraction ===", + "", + "@guppy", + "def syndrome_extraction(", + f" surf: {info['struct_name']},", + " ax: qubit,", + " az: qubit,", + f") -> {info['syndrome_name']}:", + ' """Extract full syndrome."""', + " # Z stabilizers", + ], + ) + + lines.extend( + f" sz{stab.index} = measure_z_stab_{stab.index}(az, surf.data)" + for stab in info["z_stabilizers"] + ) + + lines.append("") + lines.append(" # X stabilizers") + + lines.extend( + f" sx{stab.index} = measure_x_stab_{stab.index}(ax, surf.data)" + for stab in info["x_stabilizers"] + ) + + lines.extend( + [ + "", + f" synx = array({x_calls})", + f" synz = array({z_calls})", + "", + f" return {info['syndrome_name']}(synx, synz)", + "", + "", + ], + ) + + # Initialization + lines.extend( + [ + "# === Initialization ===", + "", + "@guppy", + f"def init_z_basis(surf: {info['struct_name']}, ax: qubit) -> array[bool, {num_x_stab}]:", + ' """Initialize logical |0_L> and extract initial X syndrome."""', + ], + ) + + lines.extend( + f" sx{stab.index} = measure_x_stab_{stab.index}(ax, surf.data)" + for stab in info["x_stabilizers"] + ) + + lines.extend( + [ + "", + f" return array({x_calls})", + "", + "", + ], + ) + + # Apply logical X + lines.extend( + [ + "@guppy", + f"def apply_logical_x(surf: {info['struct_name']}) -> None:", + ' """Apply logical X operator."""', + ], + ) + lines.extend(f" x(surf.data[{q}])" for q in info["logical_x"]) + lines.extend( + [ + "", + "", + ], + ) + + # Transversal CNOT + lines.extend( + [ + "# === Transversal Operations ===", + "", + "@guppy", + f"def transversal_cnot(ctrl: {info['struct_name']}, tgt: {info['struct_name']}) -> None:", + ' """Apply transversal CNOT: ctrl[i] controls tgt[i]."""', + f" for i in range({num_data}):", + " cx(ctrl.data[i], tgt.data[i])", + "", + "", + ], + ) + + # Measurement + lines.extend( + [ + "# === Measurement ===", + "", + "@guppy", + f"def measure_z_basis(surf: {info['struct_name']} @ owned) -> array[bool, {num_data}]:", + ' """Destructively measure in Z basis."""', + " return measure_array(surf.data)", + "", + "", + ], + ) + + # Factory functions + _add_transversal_factory_functions(lines, info, num_data, num_x_stab) + + return "\n".join(lines) + + +def generate_color_transversal_source(d: int) -> str: + """Generate transversal CNOT source for color codes.""" + info = _get_color_code_info(d) + num_data = info["num_data"] + num_stab = info["num_x_stab"] # Same for X and Z + + lines = [ + f'"""Transversal CNOT for distance-{d} color codes.', + "", + "Auto-generated for logical CNOT between two patches.", + '"""', + "", + "from guppylang import guppy", + "from guppylang.std.builtins import array, owned, result, comptime", + "from guppylang.std.quantum import cx, discard, h, measure, measure_array, qubit, x", + "from guppylang.std.qsystem import measure_and_reset", + "", + "", + ] + + # Struct definitions + lines.extend( + [ + "@guppy.struct", + f"class {info['struct_name']}:", + f' """Color code patch d={d}."""', + "", + f" data: array[qubit, {num_data}]", + "", + "", + "@guppy.struct", + f"class {info['syndrome_name']}:", + f' """Syndrome for d={d} color code."""', + "", + f" synx: array[bool, {num_stab}]", + f" synz: array[bool, {num_stab}]", + "", + "", + ], + ) + + # X stabilizer measurements (H-CNOT-H pattern) + lines.append("# === X Stabilizer Measurements ===") + lines.append("") + + for stab in info["stabilizers"]: + lines.extend( + [ + "@guppy", + f"def measure_x_stab_{stab.index}(ax: qubit, data: array[qubit, {num_data}]) -> bool:", + f' """Measure X stabilizer {stab.index} ({stab.color})."""', + " h(ax)", + ], + ) + lines.extend(f" cx(ax, data[{q}])" for q in stab.qubits) + lines.extend( + [ + " h(ax)", + " return measure_and_reset(ax)", + "", + "", + ], + ) + + # Z stabilizer measurements + lines.append("# === Z Stabilizer Measurements ===") + lines.append("") + + for stab in info["stabilizers"]: + lines.extend( + [ + "@guppy", + f"def measure_z_stab_{stab.index}(az: qubit, data: array[qubit, {num_data}]) -> bool:", + f' """Measure Z stabilizer {stab.index} ({stab.color})."""', + ], + ) + lines.extend(f" cx(data[{q}], az)" for q in stab.qubits) + lines.extend( + [ + " return measure_and_reset(az)", + "", + "", + ], + ) + + # Syndrome extraction + x_calls = ", ".join(f"sx{s.index}" for s in info["stabilizers"]) + z_calls = ", ".join(f"sz{s.index}" for s in info["stabilizers"]) + + lines.extend( + [ + "# === Syndrome Extraction ===", + "", + "@guppy", + "def syndrome_extraction(", + f" code: {info['struct_name']},", + " ax: qubit,", + " az: qubit,", + f") -> {info['syndrome_name']}:", + ' """Extract full syndrome."""', + " # Z stabilizers first", + ], + ) + + lines.extend( + f" sz{stab.index} = measure_z_stab_{stab.index}(az, code.data)" + for stab in info["stabilizers"] + ) + + lines.append("") + lines.append(" # X stabilizers") + + lines.extend( + f" sx{stab.index} = measure_x_stab_{stab.index}(ax, code.data)" + for stab in info["stabilizers"] + ) + + lines.extend( + [ + "", + f" synx = array({x_calls})", + f" synz = array({z_calls})", + "", + f" return {info['syndrome_name']}(synx, synz)", + "", + "", + ], + ) + + # Initialization + lines.extend( + [ + "# === Initialization ===", + "", + "@guppy", + f"def init_z_basis(code: {info['struct_name']}, ax: qubit) -> array[bool, {num_stab}]:", + ' """Initialize logical |0_L> and extract initial X syndrome."""', + ], + ) + + lines.extend( + f" sx{stab.index} = measure_x_stab_{stab.index}(ax, code.data)" + for stab in info["stabilizers"] + ) + + lines.extend( + [ + "", + f" return array({x_calls})", + "", + "", + ], + ) + + # Apply logical X + lines.extend( + [ + "@guppy", + f"def apply_logical_x(code: {info['struct_name']}) -> None:", + ' """Apply logical X operator."""', + ], + ) + lines.extend(f" x(code.data[{q}])" for q in info["logical_x"]) + lines.extend( + [ + "", + "", + ], + ) + + # Transversal CNOT + lines.extend( + [ + "# === Transversal Operations ===", + "", + "@guppy", + f"def transversal_cnot(ctrl: {info['struct_name']}, tgt: {info['struct_name']}) -> None:", + ' """Apply transversal CNOT: ctrl[i] controls tgt[i]."""', + f" for i in range({num_data}):", + " cx(ctrl.data[i], tgt.data[i])", + "", + "", + ], + ) + + # Measurement + lines.extend( + [ + "# === Measurement ===", + "", + "@guppy", + f"def measure_z_basis(code: {info['struct_name']} @ owned) -> array[bool, {num_data}]:", + ' """Destructively measure in Z basis."""', + " return measure_array(code.data)", + "", + "", + ], + ) + + # Factory functions + _add_color_transversal_factory_functions(lines, info, num_data, num_stab) + + return "\n".join(lines) + + +def _add_transversal_factory_functions( + lines: list[str], + info: dict, + num_data: int, + _num_stab: int, +) -> None: + """Add factory functions for surface code transversal experiments.""" + struct_name = info["struct_name"] + + lines.extend( + [ + "# === Transversal Experiments ===", + "", + "def make_transversal_cnot(num_rounds: int):", + ' """Create transversal CNOT experiment: |0_L>|0_L> -> |0_L>|0_L>."""', + "", + " @guppy", + " def transversal_cnot_exp() -> None:", + ' """Transversal CNOT experiment."""', + f" ctrl_data = array(qubit() for _ in range({num_data}))", + f" tgt_data = array(qubit() for _ in range({num_data}))", + " ax_ctrl = qubit()", + " az_ctrl = qubit()", + " ax_tgt = qubit()", + " az_tgt = qubit()", + "", + f" ctrl = {struct_name}(ctrl_data)", + f" tgt = {struct_name}(tgt_data)", + "", + " # Initialize both patches in |0_L>", + " init_syn_ctrl = init_z_basis(ctrl, ax_ctrl)", + " init_syn_tgt = init_z_basis(tgt, ax_tgt)", + ' result("init_synx_ctrl", init_syn_ctrl)', + ' result("init_synx_tgt", init_syn_tgt)', + "", + " # Apply transversal CNOT", + " transversal_cnot(ctrl, tgt)", + "", + " # Syndrome extraction rounds", + " for _t in range(comptime(num_rounds)):", + " syn_ctrl = syndrome_extraction(ctrl, ax_ctrl, az_ctrl)", + " syn_tgt = syndrome_extraction(tgt, ax_tgt, az_tgt)", + ' result("synx_ctrl", syn_ctrl.synx)', + ' result("synz_ctrl", syn_ctrl.synz)', + ' result("synx_tgt", syn_tgt.synx)', + ' result("synz_tgt", syn_tgt.synz)', + "", + " # Final measurement", + " final_ctrl = measure_z_basis(ctrl)", + " final_tgt = measure_z_basis(tgt)", + ' result("final_ctrl", final_ctrl)', + ' result("final_tgt", final_tgt)', + "", + " discard(ax_ctrl)", + " discard(az_ctrl)", + " discard(ax_tgt)", + " discard(az_tgt)", + "", + " return transversal_cnot_exp", + "", + "", + "def make_transversal_cnot_with_x(num_rounds: int):", + ' """Create transversal CNOT experiment: |1_L>|0_L> -> |1_L>|1_L>."""', + "", + " @guppy", + " def transversal_cnot_with_x_exp() -> None:", + ' """Transversal CNOT with X experiment."""', + f" ctrl_data = array(qubit() for _ in range({num_data}))", + f" tgt_data = array(qubit() for _ in range({num_data}))", + " ax_ctrl = qubit()", + " az_ctrl = qubit()", + " ax_tgt = qubit()", + " az_tgt = qubit()", + "", + f" ctrl = {struct_name}(ctrl_data)", + f" tgt = {struct_name}(tgt_data)", + "", + " # Initialize both patches in |0_L>", + " init_syn_ctrl = init_z_basis(ctrl, ax_ctrl)", + " init_syn_tgt = init_z_basis(tgt, ax_tgt)", + ' result("init_synx_ctrl", init_syn_ctrl)', + ' result("init_synx_tgt", init_syn_tgt)', + "", + " # Apply logical X to control to get |1_L>", + " apply_logical_x(ctrl)", + "", + " # Apply transversal CNOT", + " transversal_cnot(ctrl, tgt)", + "", + " # Syndrome extraction rounds", + " for _t in range(comptime(num_rounds)):", + " syn_ctrl = syndrome_extraction(ctrl, ax_ctrl, az_ctrl)", + " syn_tgt = syndrome_extraction(tgt, ax_tgt, az_tgt)", + ' result("synx_ctrl", syn_ctrl.synx)', + ' result("synz_ctrl", syn_ctrl.synz)', + ' result("synx_tgt", syn_tgt.synx)', + ' result("synz_tgt", syn_tgt.synz)', + "", + " # Final measurement", + " final_ctrl = measure_z_basis(ctrl)", + " final_tgt = measure_z_basis(tgt)", + ' result("final_ctrl", final_ctrl)', + ' result("final_tgt", final_tgt)', + "", + " discard(ax_ctrl)", + " discard(az_ctrl)", + " discard(ax_tgt)", + " discard(az_tgt)", + "", + " return transversal_cnot_with_x_exp", + "", + ], + ) + + +def _add_color_transversal_factory_functions( + lines: list[str], + info: dict, + num_data: int, + _num_stab: int, +) -> None: + """Add factory functions for color code transversal experiments.""" + struct_name = info["struct_name"] + + lines.extend( + [ + "# === Transversal Experiments ===", + "", + "def make_transversal_cnot(num_rounds: int):", + ' """Create transversal CNOT experiment: |0_L>|0_L> -> |0_L>|0_L>."""', + "", + " @guppy", + " def transversal_cnot_exp() -> None:", + ' """Transversal CNOT experiment."""', + f" ctrl_data = array(qubit() for _ in range({num_data}))", + f" tgt_data = array(qubit() for _ in range({num_data}))", + " ax_ctrl = qubit()", + " az_ctrl = qubit()", + " ax_tgt = qubit()", + " az_tgt = qubit()", + "", + f" ctrl = {struct_name}(ctrl_data)", + f" tgt = {struct_name}(tgt_data)", + "", + " # Initialize both patches in |0_L>", + " init_syn_ctrl = init_z_basis(ctrl, ax_ctrl)", + " init_syn_tgt = init_z_basis(tgt, ax_tgt)", + ' result("init_synx_ctrl", init_syn_ctrl)', + ' result("init_synx_tgt", init_syn_tgt)', + "", + " # Apply transversal CNOT", + " transversal_cnot(ctrl, tgt)", + "", + " # Syndrome extraction rounds", + " for _t in range(comptime(num_rounds)):", + " syn_ctrl = syndrome_extraction(ctrl, ax_ctrl, az_ctrl)", + " syn_tgt = syndrome_extraction(tgt, ax_tgt, az_tgt)", + ' result("synx_ctrl", syn_ctrl.synx)', + ' result("synz_ctrl", syn_ctrl.synz)', + ' result("synx_tgt", syn_tgt.synx)', + ' result("synz_tgt", syn_tgt.synz)', + "", + " # Final measurement", + " final_ctrl = measure_z_basis(ctrl)", + " final_tgt = measure_z_basis(tgt)", + ' result("final_ctrl", final_ctrl)', + ' result("final_tgt", final_tgt)', + "", + " discard(ax_ctrl)", + " discard(az_ctrl)", + " discard(ax_tgt)", + " discard(az_tgt)", + "", + " return transversal_cnot_exp", + "", + "", + "def make_transversal_cnot_with_x(num_rounds: int):", + ' """Create transversal CNOT experiment: |1_L>|0_L> -> |1_L>|1_L>."""', + "", + " @guppy", + " def transversal_cnot_with_x_exp() -> None:", + ' """Transversal CNOT with X experiment."""', + f" ctrl_data = array(qubit() for _ in range({num_data}))", + f" tgt_data = array(qubit() for _ in range({num_data}))", + " ax_ctrl = qubit()", + " az_ctrl = qubit()", + " ax_tgt = qubit()", + " az_tgt = qubit()", + "", + f" ctrl = {struct_name}(ctrl_data)", + f" tgt = {struct_name}(tgt_data)", + "", + " # Initialize both patches in |0_L>", + " init_syn_ctrl = init_z_basis(ctrl, ax_ctrl)", + " init_syn_tgt = init_z_basis(tgt, ax_tgt)", + ' result("init_synx_ctrl", init_syn_ctrl)', + ' result("init_synx_tgt", init_syn_tgt)', + "", + " # Apply logical X to control to get |1_L>", + " apply_logical_x(ctrl)", + "", + " # Apply transversal CNOT", + " transversal_cnot(ctrl, tgt)", + "", + " # Syndrome extraction rounds", + " for _t in range(comptime(num_rounds)):", + " syn_ctrl = syndrome_extraction(ctrl, ax_ctrl, az_ctrl)", + " syn_tgt = syndrome_extraction(tgt, ax_tgt, az_tgt)", + ' result("synx_ctrl", syn_ctrl.synx)', + ' result("synz_ctrl", syn_ctrl.synz)', + ' result("synx_tgt", syn_tgt.synx)', + ' result("synz_tgt", syn_tgt.synz)', + "", + " # Final measurement", + " final_ctrl = measure_z_basis(ctrl)", + " final_tgt = measure_z_basis(tgt)", + ' result("final_ctrl", final_ctrl)', + ' result("final_tgt", final_tgt)', + "", + " discard(ax_ctrl)", + " discard(az_ctrl)", + " discard(ax_tgt)", + " discard(az_tgt)", + "", + " return transversal_cnot_with_x_exp", + "", + ], + ) + + +def _load_css_transversal_module(code_type: CSSCodeType, d: int) -> dict: + """Load a transversal module for the given code type and distance.""" + cache_key = f"{code_type.value}_d{d}" + + if cache_key in _state.css_transversal_cache: + return _state.css_transversal_cache[cache_key] + + # Generate source based on code type + if code_type == CSSCodeType.SURFACE: + source = generate_surface_transversal_source(d) + elif code_type == CSSCodeType.COLOR: + source = generate_color_transversal_source(d) + else: + msg = f"Unsupported code type: {code_type}" + raise ValueError(msg) + + # Write to temp file + temp_dir = _get_temp_dir() + temp_file = temp_dir / f"css_trans_{cache_key}.py" + temp_file.write_text(source) + + # Load module + module_name = f"pecos._generated.css_trans_{cache_key}" + spec = importlib.util.spec_from_file_location(module_name, temp_file) + if spec is None or spec.loader is None: + msg = f"Failed to create module spec for {temp_file}" + raise RuntimeError(msg) + + module = importlib.util.module_from_spec(spec) + sys.modules[module_name] = module + spec.loader.exec_module(module) + + _state.css_transversal_cache[cache_key] = vars(module) + return _state.css_transversal_cache[cache_key] + + +# === Public API === + + +def make_css_transversal_cnot( + code_type: CSSCodeType | str, + distance: int, + num_rounds: int = 1, +) -> object: + """Create a transversal CNOT experiment for any CSS code. + + Args: + code_type: Type of CSS code ("surface" or "color") + distance: Code distance (must be odd >= 3) + num_rounds: Number of syndrome extraction rounds + + Returns: + Guppy function for the experiment + + Example: + >>> prog = make_css_transversal_cnot("color", distance=3, num_rounds=1) + >>> result = prog.emulator(n_qubits=18).stabilizer_sim().run() + """ + if isinstance(code_type, str): + code_type = CSSCodeType(code_type) + + if distance < 3 or distance % 2 == 0: + msg = f"Distance must be odd >= 3, got {distance}" + raise ValueError(msg) + + module = _load_css_transversal_module(code_type, distance) + return module["make_transversal_cnot"](num_rounds) + + +def make_css_transversal_cnot_with_x( + code_type: CSSCodeType | str, + distance: int, + num_rounds: int = 1, +) -> object: + """Create a transversal CNOT experiment with logical X on control. + + This tests |1_L>|0_L> -> |1_L>|1_L>. + + Args: + code_type: Type of CSS code ("surface" or "color") + distance: Code distance (must be odd >= 3) + num_rounds: Number of syndrome extraction rounds + + Returns: + Guppy function for the experiment + """ + if isinstance(code_type, str): + code_type = CSSCodeType(code_type) + + if distance < 3 or distance % 2 == 0: + msg = f"Distance must be odd >= 3, got {distance}" + raise ValueError(msg) + + module = _load_css_transversal_module(code_type, distance) + return module["make_transversal_cnot_with_x"](num_rounds) + + +def get_transversal_num_qubits(code_type: CSSCodeType | str, distance: int) -> int: + """Get total qubit count for transversal CNOT between two patches. + + Args: + code_type: Type of CSS code + distance: Code distance + + Returns: + Total qubits needed (2 * num_data + 4 ancillas) + """ + if isinstance(code_type, str): + code_type = CSSCodeType(code_type) + + if code_type == CSSCodeType.SURFACE: + num_data = distance * distance + elif code_type == CSSCodeType.COLOR: + from pecos.qec.color import ColorCode488 # noqa: PLC0415 + + code = ColorCode488.create(distance=distance) + num_data = code.num_data + else: + msg = f"Unsupported code type: {code_type}" + raise ValueError(msg) + + # Two patches + 4 ancillas (ax, az for each patch) + return 2 * num_data + 4 + + +# === Convenience functions for specific codes === + + +def make_color_transversal_cnot(distance: int, num_rounds: int = 1) -> object: + """Create transversal CNOT for color codes.""" + return make_css_transversal_cnot(CSSCodeType.COLOR, distance, num_rounds) + + +def make_color_transversal_cnot_with_x(distance: int, num_rounds: int = 1) -> object: + """Create transversal CNOT with X for color codes.""" + return make_css_transversal_cnot_with_x(CSSCodeType.COLOR, distance, num_rounds) + + +def make_color_transversal_cnot_d3(num_rounds: int = 1) -> object: + """Create d=3 transversal CNOT for color codes.""" + return make_color_transversal_cnot(3, num_rounds) + + +def make_color_transversal_cnot_with_x_d3(num_rounds: int = 1) -> object: + """Create d=3 transversal CNOT with X for color codes.""" + return make_color_transversal_cnot_with_x(3, num_rounds) + + +def make_surface_transversal_cnot(distance: int, num_rounds: int = 1) -> object: + """Create transversal CNOT for surface codes.""" + return make_css_transversal_cnot(CSSCodeType.SURFACE, distance, num_rounds) + + +def make_surface_transversal_cnot_with_x(distance: int, num_rounds: int = 1) -> object: + """Create transversal CNOT with X for surface codes.""" + return make_css_transversal_cnot_with_x(CSSCodeType.SURFACE, distance, num_rounds) diff --git a/python/quantum-pecos/src/pecos/qec/__init__.py b/python/quantum-pecos/src/pecos/qec/__init__.py new file mode 100644 index 000000000..efc5a6b5d --- /dev/null +++ b/python/quantum-pecos/src/pecos/qec/__init__.py @@ -0,0 +1,119 @@ +# Copyright 2024 The PECOS Developers +# Licensed under the Apache License, Version 2.0 + +"""Pure QEC geometry and abstractions. + +This module provides code-agnostic QEC geometry and data structures +with no SLR or runtime dependencies. + +Submodules: + analysis: Result analysis and post-processing utilities + generic: Generic stabilizer check framework + protocols: Protocol geometry (MSD, etc.) + surface: Surface code geometry (square and rotated lattices) + color: Color code geometry (4.8.8 triangular layout) + +Example: + >>> from pecos.qec.surface import compute_x_stabilizer_supports + >>> stabs = compute_x_stabilizer_supports(d=3) + >>> print(f"X stabilizers: {len(stabs)}") + + >>> from pecos.qec.color import ColorCode488 + >>> code = ColorCode488.create(distance=3) + >>> print(f"Data qubits: {code.num_data}") +""" + +from pecos.qec import analysis, color, protocols, surface +from pecos.qec.analysis import ( + logical_error_rate, + logical_fidelity, + logical_from_data, + logical_x_from_data, + logical_z_from_data, + lower_bound_fidelity, + syndrome_difference, + syndrome_to_detection_events, +) +from pecos.qec.color import ( + ColorCode488, + ColorCode488Builder, + ColorCode488Geometry, + ColorCodeStabilizer, + generate_488_layout, +) +from pecos.qec.generic import ( + CheckSchedule, + PauliOperator, + PauliType, + StabilizerCheck, +) +from pecos.qec.protocols import ( + InnerCodeGeometry, + MSDProtocol, + OuterCodeGeometry, + create_msd_protocol, +) +from pecos.qec.surface import ( + LogicalOperator, + PatchGeometry, + PatchOrientation, + Stabilizer, + StabilizerSupport, + SurfacePatch, + SurfacePatchBuilder, + compute_x_stabilizer_supports, + compute_z_stabilizer_supports, + generate_nonrotated_surface_layout, + generate_surface_layout, + parity_matrix_x, + parity_matrix_z, +) + +__all__ = [ # noqa: RUF022 + # Submodules + "analysis", + "color", + "protocols", + "surface", + # Analysis utilities + "logical_error_rate", + "logical_fidelity", + "logical_from_data", + "logical_x_from_data", + "logical_z_from_data", + "lower_bound_fidelity", + "syndrome_difference", + "syndrome_to_detection_events", + # Generic + "CheckSchedule", + "PauliOperator", + "PauliType", + "StabilizerCheck", + # Protocols - MSD + "InnerCodeGeometry", + "MSDProtocol", + "OuterCodeGeometry", + "create_msd_protocol", + # Surface code - rotated (most common, default) + "generate_surface_layout", + # Surface code - non-rotated + "compute_x_stabilizer_supports", + "compute_z_stabilizer_supports", + "generate_nonrotated_surface_layout", + "parity_matrix_x", + "parity_matrix_z", + # Surface code - patch classes + "LogicalOperator", + "PatchGeometry", + "PatchOrientation", + "Stabilizer", + "StabilizerSupport", + "SurfacePatch", + "SurfacePatchBuilder", + # Color code + "ColorCode488", + "ColorCode488Builder", + "ColorCode488Geometry", + "ColorCodeStabilizer", + "generate_488_layout", +] diff --git a/python/quantum-pecos/src/pecos/qec/analysis.py b/python/quantum-pecos/src/pecos/qec/analysis.py new file mode 100644 index 000000000..12ede0927 --- /dev/null +++ b/python/quantum-pecos/src/pecos/qec/analysis.py @@ -0,0 +1,224 @@ +# Copyright 2024 The PECOS Developers +# Licensed under the Apache License, Version 2.0 + +"""QEC result analysis and post-processing utilities. + +This module provides utilities for analyzing quantum error correction +results, including logical operator extraction, fidelity calculation, +and syndrome processing. +""" + +from __future__ import annotations + +import math +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from collections.abc import Sequence + + +def logical_x_from_data(d: int, data: Sequence[int]) -> int: + """Extract logical X value from measurement data. + + For a surface code, the logical X operator is supported on the + left column of data qubits (indices 0, d, 2d, ...). + + Args: + d: Code distance. + data: Measurement outcomes for d^2 data qubits. + + Returns: + Logical X value (0 or 1) computed as XOR of left column. + """ + if len(data) != d * d: + msg = f"Expected {d*d} data qubits, got {len(data)}" + raise ValueError(msg) + + result = 0 + for i in range(d): + result ^= data[i * d] + return result + + +def logical_z_from_data(d: int, data: Sequence[int]) -> int: + """Extract logical Z value from measurement data. + + For a surface code, the logical Z operator is supported on the + top row of data qubits (indices 0, 1, 2, ..., d-1). + + Args: + d: Code distance. + data: Measurement outcomes for d^2 data qubits. + + Returns: + Logical Z value (0 or 1) computed as XOR of top row. + """ + if len(data) != d * d: + msg = f"Expected {d*d} data qubits, got {len(data)}" + raise ValueError(msg) + + result = 0 + for i in range(d): + result ^= data[i] + return result + + +def logical_from_data(d: int, data: Sequence[int]) -> tuple[int, int]: + """Extract both logical X and Z values from measurement data. + + Args: + d: Code distance. + data: Measurement outcomes for d^2 data qubits. + + Returns: + Tuple of (logical_x, logical_z) values. + """ + return logical_x_from_data(d, data), logical_z_from_data(d, data) + + +def logical_fidelity( + outcomes: Sequence[Sequence[int]], + d: int, + basis: int, + expected: int = 0, +) -> tuple[float, float]: + """Compute logical fidelity from multiple measurement outcomes. + + Calculates the fraction of shots where the logical measurement + matches the expected value, with binomial error bars. + + Args: + outcomes: List of measurement outcomes, each with d^2 data qubits. + d: Code distance. + basis: Measurement basis (0=X, 1=Z). + expected: Expected logical value (default 0). + + Returns: + Tuple of (fidelity, error) where error is the standard deviation + assuming binomial statistics: sqrt(f * (1-f) / num_shots). + """ + if not outcomes: + msg = "No outcomes provided" + raise ValueError(msg) + + num_shots = len(outcomes) + successes = 0 + + for data in outcomes: + logical = ( + logical_x_from_data(d, data) if basis == 0 else logical_z_from_data(d, data) + ) + + if logical == expected: + successes += 1 + + fidelity = successes / num_shots + + # Binomial error bar + error = ( + 0.0 + if fidelity == 0.0 or fidelity == 1.0 + else math.sqrt(fidelity * (1 - fidelity) / num_shots) + ) + + return fidelity, error + + +def syndrome_difference( + syndromes: Sequence[Sequence[int]], +) -> list[list[int]]: + """Compute syndrome differences between consecutive rounds. + + For MWPM decoding, we need the syndrome changes (differences) + between rounds rather than the raw syndromes. The first round + is compared against all-zeros (initialization). + + Args: + syndromes: List of syndrome measurements, one per round. + Each syndrome is a sequence of stabilizer measurement results. + + Returns: + List of syndrome differences. The i-th difference is + syndromes[i] XOR syndromes[i-1] (with syndromes[-1] = 0). + """ + if not syndromes: + return [] + + num_stab = len(syndromes[0]) + result = [] + + # First round: difference from all-zeros + result.append(list(syndromes[0])) + + # Subsequent rounds: difference from previous + for i in range(1, len(syndromes)): + diff = [syndromes[i][j] ^ syndromes[i - 1][j] for j in range(num_stab)] + result.append(diff) + + return result + + +def syndrome_to_detection_events( + syndromes: Sequence[Sequence[int]], +) -> list[tuple[int, int]]: + """Convert syndrome history to detection event coordinates. + + Detection events are (stabilizer_index, round) pairs where + the syndrome changed (difference is 1). + + Args: + syndromes: List of syndrome measurements, one per round. + + Returns: + List of (stabilizer_index, round) tuples for each detection event. + """ + differences = syndrome_difference(syndromes) + events = [] + + for t, diff in enumerate(differences): + for s, val in enumerate(diff): + if val == 1: + events.append((s, t)) + + return events + + +def logical_error_rate( + outcomes: Sequence[Sequence[int]], + d: int, + basis: int, + expected: int = 0, +) -> tuple[float, float]: + """Compute logical error rate from measurement outcomes. + + This is simply 1 - fidelity, with propagated error bars. + + Args: + outcomes: List of measurement outcomes, each with d^2 data qubits. + d: Code distance. + basis: Measurement basis (0=X, 1=Z). + expected: Expected logical value (default 0). + + Returns: + Tuple of (error_rate, error_bar). + """ + fidelity, error = logical_fidelity(outcomes, d, basis, expected) + return 1 - fidelity, error + + +def lower_bound_fidelity(f1: float, f2: float) -> float: + """Compute lower bound on true fidelity from two measurements. + + Uses the formula: bound = (4/5) * (f1 + f2) - (3/5) + + This provides a statistical lower bound accounting for + measurement correlations when measuring in two different bases. + + Args: + f1: Fidelity from first measurement basis. + f2: Fidelity from second measurement basis. + + Returns: + Lower bound on true fidelity. + """ + return (4 / 5) * (f1 + f2) - (3 / 5) diff --git a/python/quantum-pecos/src/pecos/qec/color/__init__.py b/python/quantum-pecos/src/pecos/qec/color/__init__.py new file mode 100644 index 000000000..95c976640 --- /dev/null +++ b/python/quantum-pecos/src/pecos/qec/color/__init__.py @@ -0,0 +1,34 @@ +# Copyright 2024 The PECOS Developers +# Licensed under the Apache License, Version 2.0 + +"""4.8.8 Triangular Color Code geometry. + +This module provides pure geometry for the 4.8.8 color code, +a topological QEC code with transversal Clifford gates. + +Classes: + ColorCode488: Main color code class + ColorCode488Geometry: Underlying geometry data + ColorCodeStabilizer: Individual stabilizer data + +Functions: + generate_488_layout: Generate the 4.8.8 lattice layout +""" + +from pecos.qec.color.code import ( + ColorCode488, + ColorCode488Builder, + ColorCode488Geometry, + ColorCodeStabilizer, +) +from pecos.qec.color.geometry import generate_488_layout + +__all__ = [ + # Code classes + "ColorCode488", + "ColorCode488Builder", + "ColorCode488Geometry", + "ColorCodeStabilizer", + # Geometry + "generate_488_layout", +] diff --git a/python/quantum-pecos/src/pecos/qec/color/code.py b/python/quantum-pecos/src/pecos/qec/color/code.py new file mode 100644 index 000000000..c88b0e985 --- /dev/null +++ b/python/quantum-pecos/src/pecos/qec/color/code.py @@ -0,0 +1,234 @@ +# Copyright 2024 The PECOS Developers +# Licensed under the Apache License, Version 2.0 + +"""4.8.8 Triangular Color Code implementation.""" + +from dataclasses import dataclass, field + +import pecos +from pecos.qec.color.geometry import generate_488_layout +from pecos.qec.generic import StabilizerCheck + + +@dataclass(frozen=True) +class ColorCodeStabilizer: + """A stabilizer in the color code. + + Attributes: + index: Unique identifier + qubits: Tuple of qubit indices + color: 'red', 'green', or 'blue' + is_boundary: Whether this is a boundary stabilizer + """ + + index: int + qubits: tuple[int, ...] + color: str + is_boundary: bool = False + + @property + def weight(self) -> int: + """Number of qubits this stabilizer acts on.""" + return len(self.qubits) + + +@dataclass +class ColorCode488Geometry: + """Geometry for a 4.8.8 color code. + + Stores the layout and stabilizer structure. + """ + + distance: int + qubit_positions: dict[int, tuple[int, int]] = field(default_factory=dict) + stabilizers: list[ColorCodeStabilizer] = field(default_factory=list) + num_data: int = field(init=False) + num_stabilizers: int = field(init=False) + + def __post_init__(self) -> None: + """Generate the layout.""" + if self.distance < 3 or self.distance % 2 == 0: + msg = f"Distance must be odd >= 3, got {self.distance}" + raise ValueError(msg) + + nodeid2pos, polygons = generate_488_layout(self.distance) + self.qubit_positions = nodeid2pos + self.num_data = len(nodeid2pos) + + # Convert polygons to stabilizers + self.stabilizers = [] + for i, polygon in enumerate(polygons): + qubits = tuple(polygon[:-1]) + color = polygon[-1] + is_boundary = len(qubits) < 4 # Boundary stabilizers have fewer qubits + + self.stabilizers.append( + ColorCodeStabilizer( + index=i, + qubits=qubits, + color=color, + is_boundary=is_boundary, + ), + ) + + self.num_stabilizers = len(self.stabilizers) + + +class ColorCode488: + """A 4.8.8 triangular color code. + + The color code is a topological QEC code with three-colored + stabilizers. It supports transversal Clifford gates. + + Example: + >>> code = ColorCode488.create(distance=3) + >>> print(f"Data qubits: {code.num_data}") + >>> print(f"Stabilizers: {code.num_stabilizers}") + """ + + def __init__(self, geometry: ColorCode488Geometry) -> None: + """Initialize with geometry.""" + self.geometry = geometry + self._cache: dict[str, object] = {} + + @classmethod + def create(cls, distance: int) -> "ColorCode488": + """Create a color code with the given distance. + + Args: + distance: Code distance (must be odd >= 3) + + Returns: + ColorCode488 instance + """ + geometry = ColorCode488Geometry(distance=distance) + return cls(geometry) + + @property + def distance(self) -> int: + """Code distance.""" + return self.geometry.distance + + @property + def num_data(self) -> int: + """Number of data qubits.""" + return self.geometry.num_data + + @property + def num_stabilizers(self) -> int: + """Number of stabilizers.""" + return self.geometry.num_stabilizers + + @property + def qubit_positions(self) -> dict[int, tuple[int, int]]: + """Qubit position mapping.""" + return self.geometry.qubit_positions + + @property + def stabilizers(self) -> list[ColorCodeStabilizer]: + """List of stabilizers.""" + return self.geometry.stabilizers + + def get_stabilizers_by_color(self, color: str) -> list[ColorCodeStabilizer]: + """Get stabilizers of a specific color. + + Args: + color: 'red', 'green', or 'blue' + + Returns: + List of stabilizers with that color + """ + return [s for s in self.stabilizers if s.color == color] + + def get_red_stabilizers(self) -> list[ColorCodeStabilizer]: + """Get red (weight-4) stabilizers.""" + return self.get_stabilizers_by_color("red") + + def get_green_stabilizers(self) -> list[ColorCodeStabilizer]: + """Get green stabilizers.""" + return self.get_stabilizers_by_color("green") + + def get_blue_stabilizers(self) -> list[ColorCodeStabilizer]: + """Get blue stabilizers.""" + return self.get_stabilizers_by_color("blue") + + def get_parity_matrix(self) -> pecos.Array: + """Get the parity check matrix. + + Returns: + PECOS array of shape (num_stabilizers, num_data) + """ + matrix = pecos.zeros((self.num_stabilizers, self.num_data), dtype="int64") + + for stab in self.stabilizers: + for q in stab.qubits: + matrix[stab.index, q] = 1 + + return matrix + + def get_logical_x(self) -> tuple[int, ...]: + """Get logical X operator qubits. + + For the triangular color code, logical X runs along one boundary. + """ + # Bottom row of qubits forms logical X + positions = self.qubit_positions + + # Find qubits with lowest y coordinate + min_y = min(pos[1] for pos in positions.values()) + logical_qubits = [qid for qid, pos in positions.items() if pos[1] == min_y] + + return tuple(sorted(logical_qubits)) + + def get_logical_z(self) -> tuple[int, ...]: + """Get logical Z operator qubits. + + For the triangular 4.8.8 color code, both logical X and logical Z + are supported on the same qubits (the bottom boundary), but with + different Pauli types (X vs Z). This is because the color code + is self-dual. + """ + # Same support as logical X for self-dual color code + return self.get_logical_x() + + def to_generic_checks(self) -> list[StabilizerCheck]: + """Convert to generic StabilizerCheck objects. + + Returns: + List of StabilizerCheck instances for use with generic framework + """ + checks = [] + for stab in self.stabilizers: + check = StabilizerCheck.x_check( + index=stab.index, + qubits=stab.qubits, + is_boundary=stab.is_boundary, + ) + # Note: Color codes measure both X and Z on same qubits + # This returns X checks; for Z checks, create z_check versions + checks.append(check) + return checks + + +class ColorCode488Builder: + """Builder for creating ColorCode488 instances. + + Example: + >>> code = ColorCode488Builder().with_distance(5).build() + """ + + def __init__(self) -> None: + """Initialize the builder.""" + self._distance: int | None = None + + def with_distance(self, distance: int) -> "ColorCode488Builder": + """Set the code distance.""" + self._distance = distance + return self + + def build(self) -> ColorCode488: + """Build the ColorCode488.""" + if self._distance is None: + msg = "Distance must be set before building" + raise ValueError(msg) + return ColorCode488.create(distance=self._distance) diff --git a/python/quantum-pecos/src/pecos/qec/color/geometry.py b/python/quantum-pecos/src/pecos/qec/color/geometry.py new file mode 100644 index 000000000..231928f64 --- /dev/null +++ b/python/quantum-pecos/src/pecos/qec/color/geometry.py @@ -0,0 +1,169 @@ +# Copyright 2024 The PECOS Developers +# Licensed under the Apache License, Version 2.0 + +"""4.8.8 Triangular Color Code geometry and layout. + +The 4.8.8 color code is a topological quantum error correction code +where qubits are arranged on a triangular lattice with stabilizers +that are colored red, green, and blue. + +Key properties: +- Three colors: red, green, blue +- Red stabilizers are weight-4 (squares) +- Green/Blue stabilizers are weight-4 or weight-8 (octagons and boundaries) +- Transversal H, S, and CNOT gates +- Distance d requires O(d^2) qubits +""" + +from typing import Any + + +def generate_488_layout( + distance: int, +) -> tuple[dict[int, tuple[int, int]], list[list[Any]]]: + """Generate the 4.8.8 color code layout. + + Creates a triangular lattice with the specified code distance. + + Args: + distance: Code distance (must be odd >= 3) + + Returns: + Tuple of (qubit positions dict, polygon list) + Each polygon is [qubit_id, ..., color_string] + """ + if distance < 3 or distance % 2 == 0: + msg = f"Distance must be odd >= 3, got {distance}" + raise ValueError(msg) + + lattice_height = 4 * distance - 4 + lattice_width = 2 * distance - 2 + pos_qubits = [] + pos_checks = [] + + for y in range(lattice_width + 1): + for x in range(lattice_height + 1): + # Skip positions outside the triangular region + if ((x, y) == (x, x + 2) and x % 2 == 1 and y % 8 == 3) or ( + (x, y) == (4 * distance - y, y) and x % 2 == 1 and y % 8 == 7 + ): + pass + elif (x, y) > (x, x) or (x, y) > (4 * distance - y - 2, y): + continue + + # Place data qubits + if x % 2 == 0 and y % 2 == 0: + if (y / 2) % 4 == 1 or (y / 2) % 4 == 2: + if (x / 2) % 4 == 2 or (x / 2) % 4 == 3: + pos_qubits.append((x, y)) + elif (x / 2) % 4 == 0 or (x / 2) % 4 == 1: + pos_qubits.append((x, y)) + + # Place check positions + if x % 4 == 1 and y % 4 == 3: + pos_checks.append((x, y)) + + if y == 0 and x % 8 == 5: + pos_checks.append((x, y)) + + # Sort positions for consistent indexing + pos_qubits = sorted(pos_qubits, key=lambda point: (-point[1], point[0])) + pos_checks = sorted(pos_checks, key=lambda point: (-point[1], point[0])) + + # Create position mappings + nodeid2pos = {i: pos_qubits[i] for i in range(len(pos_qubits))} + pos2nodeid = {v: k for k, v in nodeid2pos.items()} + + # Find polygons (stabilizers) + polygons = [] + for x, y in pos_checks: + if square := _find_square(x, y, pos2nodeid): + polygons.append(square) + elif y == 0 and (gon := _find_bottom_polygon(x, y, pos2nodeid)): + polygons.append(gon) + elif octo := _find_octagon(x, y, pos2nodeid): + polygons.append(octo) + + return nodeid2pos, polygons + + +def _find_square( + x: int, + y: int, + pos2nodeid: dict[tuple[int, int], int], +) -> list[Any] | None: + """Find a square (weight-4) stabilizer at position.""" + square_coords = [(x - 1, y + 1), (x - 1, y - 1), (x + 1, y - 1), (x + 1, y + 1)] + square_ids = [] + + for coord in square_coords: + nid = pos2nodeid.get(coord) + if nid is None: + return None + square_ids.append(nid) + + square_ids.append("red") + return square_ids + + +def _find_octagon( + x: int, + y: int, + pos2nodeid: dict[tuple[int, int], int], +) -> list[Any] | None: + """Find an octagon (weight-8) stabilizer at position.""" + octagon_coords = [ + (x - 1, y + 3), + (x - 3, y + 1), + (x - 3, y - 1), + (x - 1, y - 3), + (x + 1, y - 3), + (x + 3, y - 1), + (x + 3, y + 1), + (x + 1, y + 3), + ] + octo_ids = [] + + for coord in octagon_coords: + nid = pos2nodeid.get(coord) + if nid is not None: + octo_ids.append(nid) + + if not octo_ids: + return None + + # Determine color based on position + if (x - 1) // 4 % 2: + octo_ids.append("green") + else: + octo_ids.append("blue") + + return octo_ids + + +def _find_bottom_polygon( + x: int, + y: int, + pos2nodeid: dict[tuple[int, int], int], +) -> list[Any] | None: + """Find a bottom boundary stabilizer.""" + coords = [ + (x - 1, y + 2), + (x - 3, y), + (x + 3, y), + (x + 1, y + 2), + ] + found_ids = [] + + for coord in coords: + nid = pos2nodeid.get(coord) + if nid is None: + return None + found_ids.append(nid) + + if (x - 1) // 4 % 2: + found_ids.append("green") + else: + found_ids.append("blue") + + return found_ids diff --git a/python/quantum-pecos/src/pecos/qec/generic/__init__.py b/python/quantum-pecos/src/pecos/qec/generic/__init__.py new file mode 100644 index 000000000..5d4e4c03d --- /dev/null +++ b/python/quantum-pecos/src/pecos/qec/generic/__init__.py @@ -0,0 +1,22 @@ +# Copyright 2024 The PECOS Developers +# Licensed under the Apache License, Version 2.0 + +"""Generic QEC abstractions. + +Code-agnostic utilities for stabilizer checks, scheduling, +and Pauli operators that work across different QEC code families. +""" + +from pecos.qec.generic.check import ( + CheckSchedule, + PauliOperator, + PauliType, + StabilizerCheck, +) + +__all__ = [ + "CheckSchedule", + "PauliOperator", + "PauliType", + "StabilizerCheck", +] diff --git a/python/quantum-pecos/src/pecos/qec/generic/check.py b/python/quantum-pecos/src/pecos/qec/generic/check.py new file mode 100644 index 000000000..70db5d5c3 --- /dev/null +++ b/python/quantum-pecos/src/pecos/qec/generic/check.py @@ -0,0 +1,222 @@ +# Copyright 2024 The PECOS Developers +# Licensed under the Apache License, Version 2.0 + +"""Generic stabilizer check framework. + +This module provides code-agnostic abstractions for stabilizer checks +that can be used across different QEC codes (surface codes, color codes, etc.). + +The framework supports: +- Arbitrary Pauli operators (X, Y, Z) on data qubits +- Weight-2 to weight-n stabilizers +- Both bulk and boundary stabilizers +- Flexible ancilla allocation +""" + +from collections.abc import Sequence +from dataclasses import dataclass +from enum import Enum + + +class PauliType(Enum): + """Pauli operator type.""" + + X = "X" + Y = "Y" + Z = "Z" + + def __str__(self) -> str: + """Return string representation.""" + return self.value + + +@dataclass(frozen=True) +class PauliOperator: + """A Pauli operator on a specific qubit. + + Attributes: + qubit: The qubit index this operator acts on + pauli: The Pauli type (X, Y, or Z) + """ + + qubit: int + pauli: PauliType + + def __str__(self) -> str: + """Return string representation (e.g., 'X0', 'Z3').""" + return f"{self.pauli.value}{self.qubit}" + + +@dataclass(frozen=True) +class StabilizerCheck: + """A generic stabilizer check. + + This represents a stabilizer measurement that can be used in any + CSS or non-CSS quantum error correction code. + + Attributes: + index: Unique identifier for this check + paulis: Sequence of Pauli operators defining the stabilizer + color: Optional color for color codes (red, green, blue) + is_boundary: Whether this is a boundary stabilizer + """ + + index: int + paulis: tuple[PauliOperator, ...] + color: str | None = None + is_boundary: bool = False + + @classmethod + def from_string( + cls, + index: int, + pauli_string: str, + qubits: Sequence[int], + *, + color: str | None = None, + is_boundary: bool = False, + ) -> "StabilizerCheck": + """Create a stabilizer check from a Pauli string. + + Args: + index: Check index + pauli_string: String like "XXXX", "ZZZZ", or "XYZX" + qubits: Qubit indices the operators act on + color: Optional color for color codes + is_boundary: Whether this is a boundary stabilizer + + Returns: + StabilizerCheck instance + + Raises: + ValueError: If pauli_string length doesn't match qubits length + """ + if len(pauli_string) == 1: + pauli_string = pauli_string * len(qubits) + + if len(pauli_string) != len(qubits): + msg = ( + f"Pauli string length ({len(pauli_string)}) must match " + f"number of qubits ({len(qubits)})" + ) + raise ValueError( + msg, + ) + + paulis = tuple( + PauliOperator(q, PauliType(p)) + for p, q in zip(pauli_string, qubits, strict=False) + ) + + return cls( + index=index, + paulis=paulis, + color=color, + is_boundary=is_boundary, + ) + + @classmethod + def x_check( + cls, + index: int, + qubits: Sequence[int], + *, + is_boundary: bool = False, + ) -> "StabilizerCheck": + """Create an X-type stabilizer check.""" + return cls.from_string(index, "X", qubits, is_boundary=is_boundary) + + @classmethod + def z_check( + cls, + index: int, + qubits: Sequence[int], + *, + is_boundary: bool = False, + ) -> "StabilizerCheck": + """Create a Z-type stabilizer check.""" + return cls.from_string(index, "Z", qubits, is_boundary=is_boundary) + + @property + def weight(self) -> int: + """Number of qubits this check acts on.""" + return len(self.paulis) + + @property + def qubits(self) -> tuple[int, ...]: + """Qubit indices this check acts on.""" + return tuple(p.qubit for p in self.paulis) + + @property + def pauli_string(self) -> str: + """Get the Pauli string representation.""" + return "".join(p.pauli.value for p in self.paulis) + + def is_css(self) -> bool: + """Check if this is a CSS stabilizer (all same Pauli type).""" + if not self.paulis: + return True + first = self.paulis[0].pauli + return all(p.pauli == first for p in self.paulis) + + def get_controlled_gate(self, pauli: PauliType) -> str: + """Get the controlled gate name for a Pauli type.""" + return { + PauliType.X: "cx", + PauliType.Y: "cy", + PauliType.Z: "cz", + }[pauli] + + +@dataclass +class CheckSchedule: + """A schedule for measuring multiple stabilizer checks. + + Organizes checks into rounds that can be measured in parallel, + respecting qubit constraints. + + Attributes: + rounds: List of rounds, each containing checks that can run in parallel + """ + + rounds: list[list[StabilizerCheck]] + + @classmethod + def sequential(cls, checks: Sequence[StabilizerCheck]) -> "CheckSchedule": + """Create a sequential schedule (one check per round).""" + return cls(rounds=[[c] for c in checks]) + + @classmethod + def parallel_by_color( + cls, + checks: Sequence[StabilizerCheck], + ) -> "CheckSchedule": + """Create a schedule that parallelizes checks by color.""" + by_color: dict[str | None, list[StabilizerCheck]] = {} + for check in checks: + color = check.color + if color not in by_color: + by_color[color] = [] + by_color[color].append(check) + + max_len = max(len(group) for group in by_color.values()) + + rounds = [] + for i in range(max_len): + round_checks = [ + color_checks[i] + for color_checks in by_color.values() + if i < len(color_checks) + ] + if round_checks: + rounds.append(round_checks) + + return cls(rounds=rounds) + + def total_checks(self) -> int: + """Total number of checks in the schedule.""" + return sum(len(r) for r in self.rounds) + + def num_rounds(self) -> int: + """Number of rounds in the schedule.""" + return len(self.rounds) diff --git a/python/quantum-pecos/src/pecos/qec/protocols/__init__.py b/python/quantum-pecos/src/pecos/qec/protocols/__init__.py new file mode 100644 index 000000000..f0c6426ae --- /dev/null +++ b/python/quantum-pecos/src/pecos/qec/protocols/__init__.py @@ -0,0 +1,22 @@ +# Copyright 2024 The PECOS Developers +# Licensed under the Apache License, Version 2.0 + +"""QEC protocol geometry and abstractions. + +This module provides geometry structures for quantum error correction +protocols like magic state distillation. +""" + +from pecos.qec.protocols.msd import ( + InnerCodeGeometry, + MSDProtocol, + OuterCodeGeometry, + create_msd_protocol, +) + +__all__ = [ + "InnerCodeGeometry", + "MSDProtocol", + "OuterCodeGeometry", + "create_msd_protocol", +] diff --git a/python/quantum-pecos/src/pecos/qec/protocols/msd.py b/python/quantum-pecos/src/pecos/qec/protocols/msd.py new file mode 100644 index 000000000..405327577 --- /dev/null +++ b/python/quantum-pecos/src/pecos/qec/protocols/msd.py @@ -0,0 +1,249 @@ +# Copyright 2024 The PECOS Developers +# Licensed under the Apache License, Version 2.0 + +"""Magic State Distillation protocol geometry. + +This module provides geometry structures for magic state distillation (MSD) +protocols using surface codes. MSD uses a two-level approach: + +1. Inner code (distance-2): Fast error detection with 4 data qubits +2. Outer code (distance-3): Full surface code protection with 9 data qubits + +The inner code acts as a filter - if errors are detected, the state is +discarded before expensive outer code expansion. + +Qubit layout (3x3 grid): + 0 1 2 + 3 4 5 + 6 7 8 + +Inner code uses qubits {0, 1, 3, 4} (top-left 2x2). +Outer code adds qubits {2, 5, 6, 7, 8} (right column and bottom row). +""" + +from dataclasses import dataclass, field + + +@dataclass(frozen=True) +class InnerCodeGeometry: + """Distance-2 inner code geometry for MSD. + + The inner code uses 4 data qubits in a 2x2 arrangement from the + top-left corner of the full 3x3 grid. + + Attributes: + data_qubits: Indices of data qubits (0, 1, 3, 4). + z_stabilizer: Data qubit indices for the Z stabilizer. + x_stabilizers: Data qubit indices for X stabilizers (top, bottom). + """ + + data_qubits: tuple[int, ...] = (0, 1, 3, 4) + + # Z stabilizer: measures Z on all 4 qubits (column-major order) + z_stabilizer: tuple[int, ...] = (0, 3, 1, 4) + + # X stabilizers: top row [0,1] and bottom row [3,4] + x_stabilizers: tuple[tuple[int, ...], ...] = ((0, 1), (3, 4)) + + @property + def num_data(self) -> int: + """Number of data qubits.""" + return len(self.data_qubits) + + @property + def num_x_stabilizers(self) -> int: + """Number of X stabilizers.""" + return len(self.x_stabilizers) + + @property + def num_z_stabilizers(self) -> int: + """Number of Z stabilizers.""" + return 1 + + @property + def num_syndromes(self) -> int: + """Total syndrome bits per round.""" + return self.num_x_stabilizers + self.num_z_stabilizers + + +@dataclass(frozen=True) +class OuterCodeGeometry: + """Distance-3 outer code geometry for MSD. + + The outer code is a full d=3 surface code with 9 data qubits. + + Attributes: + data_qubits: Indices of all 9 data qubits. + inner_qubits: Indices that come from inner code (0, 1, 3, 4). + expansion_qubits: New qubits added for outer code (2, 5, 6, 7, 8). + x_stabilizers: X stabilizer supports (4 total: 2 bulk, 2 boundary). + z_stabilizers: Z stabilizer supports (4 total: 2 bulk, 2 boundary). + """ + + data_qubits: tuple[int, ...] = (0, 1, 2, 3, 4, 5, 6, 7, 8) + inner_qubits: tuple[int, ...] = (0, 1, 3, 4) + expansion_qubits: tuple[int, ...] = (2, 5, 6, 7, 8) + + # X stabilizers (4 total) + # Boundary: [0,1] (top), [7,8] (bottom) + # Bulk: [1,2,4,5], [3,4,6,7] + x_stabilizers: tuple[tuple[int, ...], ...] = ( + (0, 1), # boundary top + (1, 2, 4, 5), # bulk + (3, 4, 6, 7), # bulk + (7, 8), # boundary bottom + ) + + # Z stabilizers (4 total) + # Boundary: [2,5] (right), [3,6] (left) + # Bulk: [0,1,3,4] (same as inner Z), [4,5,7,8] + z_stabilizers: tuple[tuple[int, ...], ...] = ( + (2, 5), # boundary right + (0, 1, 3, 4), # bulk (inner code stabilizer) + (4, 5, 7, 8), # bulk + (3, 6), # boundary left + ) + + @property + def num_data(self) -> int: + """Number of data qubits.""" + return len(self.data_qubits) + + @property + def num_expansion(self) -> int: + """Number of qubits added during expansion.""" + return len(self.expansion_qubits) + + @property + def num_x_stabilizers(self) -> int: + """Number of X stabilizers.""" + return len(self.x_stabilizers) + + @property + def num_z_stabilizers(self) -> int: + """Number of Z stabilizers.""" + return len(self.z_stabilizers) + + @property + def num_syndromes(self) -> int: + """Total syndrome bits per round.""" + return self.num_x_stabilizers + self.num_z_stabilizers + + def get_bulk_x_stabilizers(self) -> tuple[tuple[int, ...], ...]: + """Get bulk (weight-4) X stabilizers.""" + return tuple(s for s in self.x_stabilizers if len(s) == 4) + + def get_boundary_x_stabilizers(self) -> tuple[tuple[int, ...], ...]: + """Get boundary (weight-2) X stabilizers.""" + return tuple(s for s in self.x_stabilizers if len(s) == 2) + + def get_bulk_z_stabilizers(self) -> tuple[tuple[int, ...], ...]: + """Get bulk (weight-4) Z stabilizers.""" + return tuple(s for s in self.z_stabilizers if len(s) == 4) + + def get_boundary_z_stabilizers(self) -> tuple[tuple[int, ...], ...]: + """Get boundary (weight-2) Z stabilizers.""" + return tuple(s for s in self.z_stabilizers if len(s) == 2) + + +@dataclass(frozen=True) +class MSDProtocol: + """Magic State Distillation protocol geometry. + + Combines inner and outer code geometry with protocol parameters. + + Attributes: + inner: Inner code geometry (distance-2). + outer: Outer code geometry (distance-3). + inner_rounds: Number of syndrome extraction rounds for inner code. + outer_rounds: Number of syndrome extraction rounds for outer code. + """ + + inner: InnerCodeGeometry = field(default_factory=InnerCodeGeometry) + outer: OuterCodeGeometry = field(default_factory=OuterCodeGeometry) + inner_rounds: int = 2 + outer_rounds: int = 1 + + @property + def total_data_qubits(self) -> int: + """Total data qubits needed (same as outer code).""" + return self.outer.num_data + + @property + def inner_syndrome_bits(self) -> int: + """Syndrome bits per inner code round.""" + return self.inner.num_syndromes + + @property + def outer_syndrome_bits(self) -> int: + """Syndrome bits per outer code round.""" + return self.outer.num_syndromes + + @property + def total_inner_syndromes(self) -> int: + """Total syndrome bits from inner code (all rounds).""" + return self.inner.num_syndromes * self.inner_rounds + + @property + def total_outer_syndromes(self) -> int: + """Total syndrome bits from outer code (all rounds).""" + return self.outer.num_syndromes * self.outer_rounds + + def get_expansion_prep_states(self) -> dict[int, str]: + """Get preparation states for expansion qubits. + + When expanding from inner to outer code: + - Bottom row qubits (6, 7, 8) are prepared in |+> + - Right column qubits (2, 5) are prepared in |0> + + Returns: + Dict mapping qubit index to preparation state ('+' or '0'). + """ + return { + 2: "0", # Right column: |0> + 5: "0", # Right column: |0> + 6: "+", # Bottom row: |+> + 7: "+", # Bottom row: |+> + 8: "+", # Bottom row: |+> + } + + def get_inner_init_states(self) -> dict[int, str]: + """Get initialization states for inner code qubits. + + For T state distillation: + - Qubit 0: T|+> (T gate applied to |+>) + - Qubit 1: |0> + - Qubits 3, 4: |+> + + Returns: + Dict mapping qubit index to preparation state. + """ + return { + 0: "T+", # T|+> magic state + 1: "0", # |0> + 3: "+", # |+> + 4: "+", # |+> + } + + +def create_msd_protocol( + inner_rounds: int = 2, + outer_rounds: int = 1, +) -> MSDProtocol: + """Create an MSD protocol with specified parameters. + + Args: + inner_rounds: Number of syndrome extraction rounds for inner code. + Default is 2 (two rounds, check for consistency). + outer_rounds: Number of syndrome extraction rounds for outer code. + Default is 1. + + Returns: + Configured MSDProtocol instance. + """ + return MSDProtocol( + inner=InnerCodeGeometry(), + outer=OuterCodeGeometry(), + inner_rounds=inner_rounds, + outer_rounds=outer_rounds, + ) diff --git a/python/quantum-pecos/src/pecos/qec/surface/__init__.py b/python/quantum-pecos/src/pecos/qec/surface/__init__.py new file mode 100644 index 000000000..a8f64c8a2 --- /dev/null +++ b/python/quantum-pecos/src/pecos/qec/surface/__init__.py @@ -0,0 +1,66 @@ +# Copyright 2024 The PECOS Developers +# Licensed under the Apache License, Version 2.0 + +"""Surface code geometry and parity matrices. + +This module provides pure geometry computations for surface codes, +including stabilizer support calculation and parity check matrices. + +Layouts: + square_lattice: Standard square lattice (d^2 data qubits) + rotated_lattice: Rotated lattice (more efficient) + +Functions: + compute_x_stabilizer_supports: Get X stabilizer qubit indices + compute_z_stabilizer_supports: Get Z stabilizer qubit indices + parity_matrix_x: Generate X parity check matrix + parity_matrix_z: Generate Z parity check matrix +""" + +from pecos.qec.surface.layouts import ( + StabilizerSupport, + compute_rotated_x_stabilizers, + compute_rotated_z_stabilizers, + compute_x_stabilizer_supports, + compute_z_stabilizer_supports, + generate_nonrotated_surface_layout, + generate_surface_layout, + get_rotated_logical_x, + get_rotated_logical_z, +) +from pecos.qec.surface.parity import ( + parity_matrix_x, + parity_matrix_z, +) +from pecos.qec.surface.patch import ( + LogicalOperator, + PatchGeometry, + PatchOrientation, + Stabilizer, + SurfacePatch, + SurfacePatchBuilder, +) + +__all__ = [ # noqa: RUF022 + # Rotated lattice (most common, default) + "compute_rotated_x_stabilizers", + "compute_rotated_z_stabilizers", + "generate_surface_layout", + "get_rotated_logical_x", + "get_rotated_logical_z", + # Non-rotated lattice + "StabilizerSupport", + "compute_x_stabilizer_supports", + "compute_z_stabilizer_supports", + "generate_nonrotated_surface_layout", + # Parity matrices + "parity_matrix_x", + "parity_matrix_z", + # Patch classes + "LogicalOperator", + "PatchGeometry", + "PatchOrientation", + "Stabilizer", + "SurfacePatch", + "SurfacePatchBuilder", +] diff --git a/python/quantum-pecos/src/pecos/qec/surface/layouts/__init__.py b/python/quantum-pecos/src/pecos/qec/surface/layouts/__init__.py new file mode 100644 index 000000000..e7cadbd97 --- /dev/null +++ b/python/quantum-pecos/src/pecos/qec/surface/layouts/__init__.py @@ -0,0 +1,49 @@ +# Copyright 2024 The PECOS Developers +# Licensed under the Apache License, Version 2.0 + +"""Surface code lattice layouts.""" + +from pecos.qec.surface.layouts.rotated_lattice import ( + RotatedPosition, + compute_rotated_x_stabilizers, + compute_rotated_z_stabilizers, + generate_surface_layout, + get_rotated_logical_x, + get_rotated_logical_z, + rotated_id_to_position, + rotated_position_to_id, +) +from pecos.qec.surface.layouts.square_lattice import ( + StabilizerSupport, + compute_x_stabilizer_supports, + compute_z_stabilizer_supports, + generate_nonrotated_surface_layout, + get_boundary_stabilizer_indices, + get_boundary_stabilizers, + get_bulk_stabilizer_indices, + get_bulk_stabilizers, + get_stabilizer_counts, +) + +__all__ = [ # noqa: RUF022 + # Rotated lattice (most common, default) + "RotatedPosition", + "compute_rotated_x_stabilizers", + "compute_rotated_z_stabilizers", + "generate_surface_layout", + "get_rotated_logical_x", + "get_rotated_logical_z", + "rotated_id_to_position", + "rotated_position_to_id", + # Non-rotated lattice + "StabilizerSupport", + "compute_x_stabilizer_supports", + "compute_z_stabilizer_supports", + "generate_nonrotated_surface_layout", + # Stabilizer categories + "get_bulk_stabilizer_indices", + "get_bulk_stabilizers", + "get_boundary_stabilizer_indices", + "get_boundary_stabilizers", + "get_stabilizer_counts", +] diff --git a/python/quantum-pecos/src/pecos/qec/surface/layouts/rotated_lattice.py b/python/quantum-pecos/src/pecos/qec/surface/layouts/rotated_lattice.py new file mode 100644 index 000000000..2d9db0e68 --- /dev/null +++ b/python/quantum-pecos/src/pecos/qec/surface/layouts/rotated_lattice.py @@ -0,0 +1,254 @@ +# Copyright 2024 The PECOS Developers +# Licensed under the Apache License, Version 2.0 + +r"""Rotated surface code lattice geometry. + +The rotated surface code arranges data qubits on a diagonal lattice, +requiring fewer physical qubits for the same code distance compared +to the standard (non-rotated) layout. + +Qubit layout for d=3 rotated code: + 0 + / \\ + 1 2 + / \\ / \\ + 3 4 5 + \\ / \\ / + 6 7 + \\ / + 8 +""" + +from dataclasses import dataclass + +from pecos.qec.surface.layouts.square_lattice import StabilizerSupport + + +@dataclass(frozen=True) +class RotatedPosition: + """Position in the rotated lattice coordinate system.""" + + x: int + y: int + + +def compute_rotated_x_stabilizers(d: int) -> list[StabilizerSupport]: + """Compute X stabilizer supports for rotated surface code. + + Args: + d: Code distance (must be odd >= 3) + + Returns: + List of StabilizerSupport for X stabilizers + """ + if d < 3 or d % 2 == 0: + msg = f"Distance must be odd >= 3, got {d}" + raise ValueError(msg) + + supports = [] + stab_idx = 0 + + # Bulk X stabilizers (weight 4) + for row in range(d - 1): + for col in range(d - 1): + if (row + col) % 2 == 0: + q_tl = row * d + col + q_tr = row * d + col + 1 + q_bl = (row + 1) * d + col + q_br = (row + 1) * d + col + 1 + + supports.append( + StabilizerSupport( + index=stab_idx, + data_qubits=(q_tl, q_tr, q_bl, q_br), + is_boundary=False, + ), + ) + stab_idx += 1 + + # Boundary X stabilizers (weight 2) - top and bottom edges + for col in range(0, d - 1, 2): + q1 = col + q2 = col + 1 + supports.append( + StabilizerSupport( + index=stab_idx, + data_qubits=(q1, q2), + is_boundary=True, + ), + ) + stab_idx += 1 + + for col in range((d - 1) % 2, d - 1, 2): + q1 = (d - 1) * d + col + q2 = (d - 1) * d + col + 1 + supports.append( + StabilizerSupport( + index=stab_idx, + data_qubits=(q1, q2), + is_boundary=True, + ), + ) + stab_idx += 1 + + supports.sort(key=lambda s: s.index) + return supports + + +def compute_rotated_z_stabilizers(d: int) -> list[StabilizerSupport]: + """Compute Z stabilizer supports for rotated surface code. + + Args: + d: Code distance (must be odd >= 3) + + Returns: + List of StabilizerSupport for Z stabilizers + """ + if d < 3 or d % 2 == 0: + msg = f"Distance must be odd >= 3, got {d}" + raise ValueError(msg) + + supports = [] + stab_idx = 0 + + # Bulk Z stabilizers (weight 4) + for row in range(d - 1): + for col in range(d - 1): + if (row + col) % 2 == 1: + q_tl = row * d + col + q_tr = row * d + col + 1 + q_bl = (row + 1) * d + col + q_br = (row + 1) * d + col + 1 + + supports.append( + StabilizerSupport( + index=stab_idx, + data_qubits=(q_tl, q_tr, q_bl, q_br), + is_boundary=False, + ), + ) + stab_idx += 1 + + # Boundary Z stabilizers (weight 2) - left and right edges + for row in range(0, d - 1, 2): + q1 = row * d + q2 = (row + 1) * d + supports.append( + StabilizerSupport( + index=stab_idx, + data_qubits=(q1, q2), + is_boundary=True, + ), + ) + stab_idx += 1 + + for row in range((d - 1) % 2, d - 1, 2): + q1 = row * d + (d - 1) + q2 = (row + 1) * d + (d - 1) + supports.append( + StabilizerSupport( + index=stab_idx, + data_qubits=(q1, q2), + is_boundary=True, + ), + ) + stab_idx += 1 + + supports.sort(key=lambda s: s.index) + return supports + + +def get_rotated_logical_x(d: int) -> tuple[int, ...]: + """Get logical X operator qubits (left edge).""" + return tuple(i * d for i in range(d)) + + +def get_rotated_logical_z(d: int) -> tuple[int, ...]: + """Get logical Z operator qubits (top edge).""" + return tuple(range(d)) + + +def rotated_id_to_position(qubit_id: int, d: int) -> tuple[int, int]: + """Convert qubit ID to (x, y) position in rotated coordinates.""" + row = qubit_id // d + col = qubit_id % d + x = col * 2 + 1 + y = (d - row) * 2 - 1 + return (x, y) + + +def rotated_position_to_id(x: int, y: int, d: int) -> int: + """Convert rotated position to qubit ID.""" + col = (x - 1) // 2 + row = d - (y + 1) // 2 + return row * d + col + + +def generate_surface_layout( + width: int, + height: int, +) -> tuple[list[tuple[int, int]], list[tuple[int, int]]]: + """Generate rotated surface code layout positions. + + This is the most common surface code variant, using d^2 data qubits for + distance d. The non-rotated variant uses more qubits; for that, use + generate_nonrotated_surface_layout() instead. + + The rotated surface code places data qubits at odd-odd positions + and ancilla qubits at even-even positions in the interior, with + boundary ancillas on the edges. + + Args: + width: Width of the patch (code distance in Z direction). + height: Height of the patch (code distance in X direction). + + Returns: + A tuple containing: + - data_positions: List of (x, y) coordinates for data qubits. + - ancilla_positions: List of (x, y) coordinates for ancilla qubits. + """ + lattice_height = 2 * height + lattice_width = 2 * width + + data_positions: list[tuple[int, int]] = [] + ancilla_positions: list[tuple[int, int]] = [] + + for y in range(lattice_height + 1): + for x in range(lattice_width + 1): + if 0 < x < lattice_width and 0 < y < lattice_height: + # Interior (no boundary stabilizers) + if x % 2 == 1 and y % 2 == 1: + # Data qubit at odd-odd positions + data_positions.append((x, y)) + elif x % 2 == 0 and y % 2 == 0: + # Ancilla at even-even positions + ancilla_positions.append((x, y)) + + elif 0 < x < lattice_width or 0 < y < lattice_height: + # Boundary ancillas (not corners) + if y == 0: + # Top edge: X stabilizers + if x != 0 and x % 4 == 0: + ancilla_positions.append((x, y)) + + elif x == 0 and (y - 2) % 4 == 0: + # Left edge + ancilla_positions.append((x, y)) + + if y == lattice_height: + # Bottom edge + if height % 2 == 0: + if x != 0 and x % 4 == 0: + ancilla_positions.append((x, y)) + elif (x - 2) % 4 == 0: + ancilla_positions.append((x, y)) + + elif x == lattice_width: + # Right edge + if width % 2 == 1: + if y != 0 and y % 4 == 0: + ancilla_positions.append((x, y)) + elif (y - 2) % 4 == 0: + ancilla_positions.append((x, y)) + + return data_positions, ancilla_positions diff --git a/python/quantum-pecos/src/pecos/qec/surface/layouts/square_lattice.py b/python/quantum-pecos/src/pecos/qec/surface/layouts/square_lattice.py new file mode 100644 index 000000000..ed9b3ecb3 --- /dev/null +++ b/python/quantum-pecos/src/pecos/qec/surface/layouts/square_lattice.py @@ -0,0 +1,325 @@ +# Copyright 2024 The PECOS Developers +# Licensed under the Apache License, Version 2.0 + +"""Standard square lattice geometry for surface codes. + +Qubit layout for distance d (example d=3): + 0 1 2 + 3 4 5 + 6 7 8 + +X stabilizers measure in checkerboard pattern with H-CNOT-H. +Z stabilizers measure in checkerboard pattern with CNOT. +""" + +from dataclasses import dataclass + + +@dataclass(frozen=True) +class StabilizerSupport: + """Definition of a single stabilizer. + + Attributes: + index: Stabilizer index in syndrome array + data_qubits: Data qubit indices this stabilizer acts on + is_boundary: True if weight-2 boundary stabilizer + """ + + index: int + data_qubits: tuple[int, ...] + is_boundary: bool + + @property + def weight(self) -> int: + """Number of data qubits in this stabilizer.""" + return len(self.data_qubits) + + +def compute_x_stabilizer_supports(d: int) -> list[StabilizerSupport]: + """Compute data qubit indices for each X stabilizer. + + X stabilizers use the H-CNOT-H pattern where the ancilla controls + CNOTs to data qubits. + + Args: + d: Code distance (must be odd >= 3) + + Returns: + List of StabilizerSupport objects, ordered by stabilizer index. + """ + num_stab = (d**2 - 1) // 2 + num_bound = d - 1 + start_bulk = num_bound // 2 + end_bulk = num_stab - start_bulk + + supports: list[StabilizerSupport] = [] + + # Bulk stabilizers (weight 4) + j = 1 + for i in range(start_bulk, end_bulk): + if j + d + 1 > d**2 - 1: + break + supports.append( + StabilizerSupport( + index=i, + data_qubits=(j, j + 1, j + d, j + d + 1), + is_boundary=False, + ), + ) + if i % (d - 1) == num_bound // 2 - 1: + j += 4 + else: + j += 2 + + # Top boundary stabilizers (weight 2) + j = 0 + for i in range(num_bound // 2): + supports.append( + StabilizerSupport( + index=i, + data_qubits=(j, j + 1), + is_boundary=True, + ), + ) + j += 2 + + # Bottom boundary stabilizers (weight 2) + j = (d - 1) * d + 1 + for i in range(num_stab - num_bound // 2, num_stab): + supports.append( + StabilizerSupport( + index=i, + data_qubits=(j, j + 1), + is_boundary=True, + ), + ) + j += 2 + + supports.sort(key=lambda s: s.index) + return supports + + +def compute_z_stabilizer_supports(d: int) -> list[StabilizerSupport]: + """Compute data qubit indices for each Z stabilizer. + + Z stabilizers use direct CNOTs from data qubits to ancilla. + + Args: + d: Code distance (must be odd >= 3) + + Returns: + List of StabilizerSupport objects, ordered by stabilizer index. + """ + num_stab = (d**2 - 1) // 2 + num_bound = d - 1 + start_bulk = num_bound // 2 + end_bulk = num_stab - start_bulk + + supports: list[StabilizerSupport] = [] + + # Bulk stabilizers (weight 4) + j = 2 * d - 2 + for i in range(start_bulk, end_bulk): + supports.append( + StabilizerSupport( + index=i, + data_qubits=(j, j + d, j + 1, j + d + 1), + is_boundary=False, + ), + ) + if i % (d - 1) == num_bound // 2 - 1: + j += 2 * d + j = j % d - 1 + d + else: + j += 2 * d + if j >= d**2: + j = (j % d) - 1 + + # Right boundary stabilizers (weight 2) + j = 2 * d - 1 + for i in range(num_bound // 2): + k = j - d + supports.append( + StabilizerSupport( + index=i, + data_qubits=(k, j), + is_boundary=True, + ), + ) + j += 2 * d + + # Left boundary stabilizers (weight 2) + j = d + for i in range(num_stab - num_bound // 2, num_stab): + k = j + d + supports.append( + StabilizerSupport( + index=i, + data_qubits=(j, k), + is_boundary=True, + ), + ) + j += 2 * d + + supports.sort(key=lambda s: s.index) + return supports + + +def get_stabilizer_counts(d: int) -> tuple[int, int, int]: + """Get stabilizer count breakdown for a surface code. + + Args: + d: Code distance (must be odd >= 3). + + Returns: + Tuple of (total_per_basis, num_bulk, num_boundary) where: + - total_per_basis: Total stabilizers per basis (X or Z) + - num_bulk: Number of weight-4 bulk stabilizers + - num_boundary: Number of weight-2 boundary stabilizers + """ + total = (d**2 - 1) // 2 + num_boundary = d - 1 + num_bulk = total - num_boundary + return total, num_bulk, num_boundary + + +def get_bulk_stabilizer_indices(d: int) -> list[int]: + """Get indices of bulk (weight-4) stabilizers. + + Bulk stabilizers are in the interior of the lattice and have + weight 4 (act on 4 data qubits). + + Args: + d: Code distance (must be odd >= 3). + + Returns: + List of stabilizer indices for bulk stabilizers. + """ + num_boundary = d - 1 + start_bulk = num_boundary // 2 + total = (d**2 - 1) // 2 + end_bulk = total - start_bulk + return list(range(start_bulk, end_bulk)) + + +def get_boundary_stabilizer_indices(d: int) -> list[int]: + """Get indices of boundary (weight-2) stabilizers. + + Boundary stabilizers are on the edges of the lattice and have + weight 2 (act on 2 data qubits). + + Args: + d: Code distance (must be odd >= 3). + + Returns: + List of stabilizer indices for boundary stabilizers. + """ + num_boundary = d - 1 + start_bulk = num_boundary // 2 + total = (d**2 - 1) // 2 + end_bulk = total - start_bulk + + # Boundary indices are before start_bulk and after end_bulk + return list(range(start_bulk)) + list(range(end_bulk, total)) + + +def get_bulk_stabilizers(d: int, stab_type: str = "X") -> list[StabilizerSupport]: + """Get bulk stabilizers for the specified type. + + Args: + d: Code distance (must be odd >= 3). + stab_type: "X" or "Z". + + Returns: + List of bulk StabilizerSupport objects. + """ + supports = ( + compute_x_stabilizer_supports(d) + if stab_type == "X" + else compute_z_stabilizer_supports(d) + ) + return [s for s in supports if not s.is_boundary] + + +def get_boundary_stabilizers(d: int, stab_type: str = "X") -> list[StabilizerSupport]: + """Get boundary stabilizers for the specified type. + + Args: + d: Code distance (must be odd >= 3). + stab_type: "X" or "Z". + + Returns: + List of boundary StabilizerSupport objects. + """ + supports = ( + compute_x_stabilizer_supports(d) + if stab_type == "X" + else compute_z_stabilizer_supports(d) + ) + return [s for s in supports if s.is_boundary] + + +def generate_nonrotated_surface_layout( + width: int, + height: int, +) -> tuple[list[tuple[int, int]], list[tuple[int, int]], list[list[tuple[int, int]]]]: + """Generate non-rotated surface code layout. + + The non-rotated surface code has data qubits on a checkerboard pattern + with more physical qubits than the rotated variant for the same distance. + For the common rotated layout, use generate_surface_layout() instead. + + Args: + width: Width of the patch (code distance in Z direction). + height: Height of the patch (code distance in X direction). + + Returns: + A tuple containing: + - data_positions: List of (x, y) coordinates for data qubits. + - ancilla_positions: List of (x, y) coordinates for ancilla qubits. + - polygons: List of polygons representing stabilizer checks. + """ + lattice_height = 2 * (height - 1) + lattice_width = 2 * (width - 1) + + data_positions: list[tuple[int, int]] = [] + ancilla_positions: list[tuple[int, int]] = [] + polygons: list[list[tuple[int, int]]] = [] + + for y in range(lattice_height + 1): + for x in range(lattice_width + 1): + if (x % 2 == 0 and y % 2 == 0) or (x % 2 == 1 and y % 2 == 1): + # Data qubit + data_positions.append((x, y)) + + elif x % 2 == 1 and y % 2 == 0: + # X ancilla + ancilla_positions.append((x, y)) + + poly: list[tuple[int, int]] = [] + if y != lattice_height: + poly.append((x, y + 1)) + if x != 0: + poly.append((x - 1, y)) + if y != 0: + poly.append((x, y - 1)) + if x != lattice_width: + poly.append((x + 1, y)) + polygons.append(poly) + + elif x % 2 == 0 and y % 2 == 1: + # Z ancilla + ancilla_positions.append((x, y)) + + poly = [] + if y != lattice_height: + poly.append((x, y + 1)) + if x != 0: + poly.append((x - 1, y)) + if y != 0: + poly.append((x, y - 1)) + if x != lattice_width: + poly.append((x + 1, y)) + polygons.append(poly) + + return data_positions, ancilla_positions, polygons diff --git a/python/quantum-pecos/src/pecos/qec/surface/parity.py b/python/quantum-pecos/src/pecos/qec/surface/parity.py new file mode 100644 index 000000000..ae3eeb5af --- /dev/null +++ b/python/quantum-pecos/src/pecos/qec/surface/parity.py @@ -0,0 +1,53 @@ +# Copyright 2024 The PECOS Developers +# Licensed under the Apache License, Version 2.0 + +"""Parity check matrix generation for surface codes.""" + +import pecos +from pecos.qec.surface.layouts import ( + compute_x_stabilizer_supports, + compute_z_stabilizer_supports, +) + + +def parity_matrix_x(d: int) -> pecos.Array: + """Generate X stabilizer parity check matrix. + + Args: + d: Code distance + + Returns: + Binary matrix of shape (num_stab, num_data) where entry (i,j)=1 + if stabilizer i acts on qubit j + """ + num_data = d * d + stabs = compute_x_stabilizer_supports(d) + num_stab = len(stabs) + + matrix = pecos.zeros((num_stab, num_data), dtype="int64") + for stab in stabs: + for q in stab.data_qubits: + matrix[stab.index, q] = 1 + + return matrix + + +def parity_matrix_z(d: int) -> pecos.Array: + """Generate Z stabilizer parity check matrix. + + Args: + d: Code distance + + Returns: + Binary matrix of shape (num_stab, num_data) + """ + num_data = d * d + stabs = compute_z_stabilizer_supports(d) + num_stab = len(stabs) + + matrix = pecos.zeros((num_stab, num_data), dtype="int64") + for stab in stabs: + for q in stab.data_qubits: + matrix[stab.index, q] = 1 + + return matrix diff --git a/python/quantum-pecos/src/pecos/qec/surface/patch.py b/python/quantum-pecos/src/pecos/qec/surface/patch.py new file mode 100644 index 000000000..696f5865d --- /dev/null +++ b/python/quantum-pecos/src/pecos/qec/surface/patch.py @@ -0,0 +1,343 @@ +# Copyright 2024 The PECOS Developers +# Licensed under the Apache License, Version 2.0 + +"""Surface code patch with runtime configuration. + +Provides a flexible, runtime-configurable surface code patch +with geometry stored as data structures. +""" + +from dataclasses import dataclass, field +from enum import Enum, auto +from typing import TYPE_CHECKING + +from pecos_rslib.num import zeros + +from pecos.qec.surface.layouts import ( + compute_rotated_x_stabilizers, + compute_rotated_z_stabilizers, + compute_x_stabilizer_supports, + compute_z_stabilizer_supports, + get_rotated_logical_x, + get_rotated_logical_z, +) + +if TYPE_CHECKING: + import pecos + + +class PatchOrientation(Enum): + """Orientation of the surface code patch boundaries.""" + + X_TOP_BOTTOM = auto() # X boundaries on top/bottom, Z on left/right + Z_TOP_BOTTOM = auto() # Z boundaries on top/bottom, X on left/right + + +@dataclass(frozen=True) +class Stabilizer: + """A stabilizer measurement in the surface code.""" + + index: int + stab_type: str # 'X' or 'Z' + data_qubits: tuple[int, ...] + is_boundary: bool + position: tuple[int, int] = (0, 0) + + @property + def weight(self) -> int: + """Number of data qubits in this stabilizer.""" + return len(self.data_qubits) + + +@dataclass(frozen=True) +class LogicalOperator: + """A logical operator for the surface code.""" + + op_type: str + data_qubits: tuple[int, ...] + + +@dataclass +class PatchGeometry: + """Geometry of a surface code patch. + + Supports both rotated (default) and standard (non-rotated) surface codes. + The rotated layout is more common and uses fewer qubits for the same distance. + """ + + dx: int + dz: int + orientation: PatchOrientation = PatchOrientation.X_TOP_BOTTOM + rotated: bool = True + + num_data: int = field(init=False) + num_x_stab: int = field(init=False) + num_z_stab: int = field(init=False) + + pos_to_id: dict[tuple[int, int], int] = field(default_factory=dict) + id_to_pos: dict[int, tuple[int, int]] = field(default_factory=dict) + + x_stabilizers: list[Stabilizer] = field(default_factory=list) + z_stabilizers: list[Stabilizer] = field(default_factory=list) + + logical_x: LogicalOperator | None = None + logical_z: LogicalOperator | None = None + + def __post_init__(self) -> None: + """Initialize computed fields and generate geometry.""" + self.num_data = self.dx * self.dz + self.num_x_stab = (self.dx * self.dz - 1) // 2 + self.num_z_stab = (self.dx * self.dz - 1) // 2 + + self._generate_layout() + self._generate_stabilizers() + self._generate_logical_operators() + + def _generate_layout(self) -> None: + for row in range(self.dx): + for col in range(self.dz): + idx = row * self.dz + col + pos = (row, col) + self.pos_to_id[pos] = idx + self.id_to_pos[idx] = pos + + def _generate_stabilizers(self) -> None: + d = min(self.dx, self.dz) + + if self.rotated: + x_supports = compute_rotated_x_stabilizers(d) + z_supports = compute_rotated_z_stabilizers(d) + else: + x_supports = compute_x_stabilizer_supports(d) + z_supports = compute_z_stabilizer_supports(d) + + self.x_stabilizers = [ + Stabilizer( + index=s.index, + stab_type="X", + data_qubits=s.data_qubits, + is_boundary=s.is_boundary, + ) + for s in x_supports + ] + + self.z_stabilizers = [ + Stabilizer( + index=s.index, + stab_type="Z", + data_qubits=s.data_qubits, + is_boundary=s.is_boundary, + ) + for s in z_supports + ] + + self.num_x_stab = len(self.x_stabilizers) + self.num_z_stab = len(self.z_stabilizers) + + def _generate_logical_operators(self) -> None: + d = min(self.dx, self.dz) + + if self.rotated: + logical_x_qubits = get_rotated_logical_x(d) + logical_z_qubits = get_rotated_logical_z(d) + else: + logical_x_qubits = tuple(i * self.dz for i in range(self.dx)) + logical_z_qubits = tuple(range(self.dz)) + + self.logical_x = LogicalOperator("X", logical_x_qubits) + self.logical_z = LogicalOperator("Z", logical_z_qubits) + + @property + def distance(self) -> int: + """Code distance (minimum of dx and dz).""" + return min(self.dx, self.dz) + + @property + def num_ancilla(self) -> int: + """Number of ancilla qubits.""" + return 2 + + @property + def num_qubits(self) -> int: + """Total number of qubits (data + ancilla).""" + return self.num_data + self.num_ancilla + + +class SurfacePatch: + """A configurable surface code patch. + + Supports both rotated (default) and standard (non-rotated) layouts. + + Example: + >>> patch = SurfacePatch.create(distance=5) # Rotated (default) + >>> patch = SurfacePatch.create(distance=5, rotated=False) # Standard + >>> patch = SurfacePatch.create(dx=3, dz=5) # Asymmetric + """ + + def __init__(self, geometry: PatchGeometry) -> None: + """Initialize a surface patch with the given geometry.""" + self.geometry = geometry + + @classmethod + def create( + cls, + distance: int | None = None, + dx: int | None = None, + dz: int | None = None, + orientation: PatchOrientation = PatchOrientation.X_TOP_BOTTOM, + *, + rotated: bool = True, + ) -> "SurfacePatch": + """Create a surface code patch. + + Args: + distance: Symmetric code distance (must be odd >= 3). + dx: X distance for asymmetric codes. + dz: Z distance for asymmetric codes. + orientation: Patch boundary orientation. + rotated: If True (default), use the rotated layout which is more + common and uses fewer qubits. If False, use the standard + (non-rotated) layout. + """ + if distance is not None: + if distance < 3 or distance % 2 == 0: + msg = f"Distance must be odd >= 3, got {distance}" + raise ValueError(msg) + dx = dx or distance + dz = dz or distance + elif dx is not None and dz is not None: + if dx < 3 or dx % 2 == 0: + msg = f"dx must be odd >= 3, got {dx}" + raise ValueError(msg) + if dz < 3 or dz % 2 == 0: + msg = f"dz must be odd >= 3, got {dz}" + raise ValueError(msg) + else: + msg = "Must provide either distance or both dx and dz" + raise ValueError(msg) + + geometry = PatchGeometry(dx=dx, dz=dz, orientation=orientation, rotated=rotated) + return cls(geometry) + + @property + def distance(self) -> int: + """Code distance (minimum of dx and dz).""" + return self.geometry.distance + + @property + def dx(self) -> int: + """X distance of the patch.""" + return self.geometry.dx + + @property + def dz(self) -> int: + """Z distance of the patch.""" + return self.geometry.dz + + @property + def num_data(self) -> int: + """Number of data qubits.""" + return self.geometry.num_data + + @property + def num_qubits(self) -> int: + """Total number of qubits (data + ancilla).""" + return self.geometry.num_qubits + + @property + def x_stabilizers(self) -> list[Stabilizer]: + """X stabilizers of the patch.""" + return self.geometry.x_stabilizers + + @property + def z_stabilizers(self) -> list[Stabilizer]: + """Z stabilizers of the patch.""" + return self.geometry.z_stabilizers + + @property + def rotated(self) -> bool: + """True if using rotated layout, False for standard layout.""" + return self.geometry.rotated + + def get_parity_matrix(self, stab_type: str) -> "pecos.Array": + """Get parity check matrix.""" + stabs = self.x_stabilizers if stab_type == "X" else self.z_stabilizers + num_stab = len(stabs) + matrix = zeros((num_stab, self.num_data), dtype="int64") + + for stab in stabs: + for q in stab.data_qubits: + matrix[stab.index, q] = 1 + + return matrix + + +class SurfacePatchBuilder: + """Builder for creating SurfacePatch instances. + + By default, creates a rotated surface code (more common). Use `.standard()` + to create a non-rotated surface code. + + Example: + >>> patch = ( + ... SurfacePatchBuilder() + ... .with_distance(5) + ... .with_orientation(PatchOrientation.Z_TOP_BOTTOM) + ... .build() + ... ) + + >>> # Non-rotated (standard) surface code: + >>> patch = SurfacePatchBuilder().with_distance(5).standard().build() + """ + + def __init__(self) -> None: + """Initialize the builder with default settings.""" + self._distance: int | None = None + self._dx: int | None = None + self._dz: int | None = None + self._orientation: PatchOrientation = PatchOrientation.X_TOP_BOTTOM + self._rotated: bool = True + + def with_distance(self, distance: int) -> "SurfacePatchBuilder": + """Set symmetric distance.""" + self._distance = distance + return self + + def with_distances(self, dx: int, dz: int) -> "SurfacePatchBuilder": + """Set asymmetric distances.""" + self._dx = dx + self._dz = dz + return self + + def with_orientation(self, orientation: PatchOrientation) -> "SurfacePatchBuilder": + """Set patch orientation.""" + self._orientation = orientation + return self + + def rotated(self) -> "SurfacePatchBuilder": + """Use rotated surface code layout (default). + + The rotated layout is more common and uses fewer physical qubits + for the same code distance. + """ + self._rotated = True + return self + + def standard(self) -> "SurfacePatchBuilder": + """Use standard (non-rotated) surface code layout. + + The standard layout uses more physical qubits but may be preferred + for certain applications or compatibility with existing code. + """ + self._rotated = False + return self + + def build(self) -> SurfacePatch: + """Build the SurfacePatch.""" + return SurfacePatch.create( + distance=self._distance, + dx=self._dx, + dz=self._dz, + orientation=self._orientation, + rotated=self._rotated, + ) diff --git a/python/quantum-pecos/src/pecos/qeccs/color_488/color_488.py b/python/quantum-pecos/src/pecos/qeccs/color_488/color_488.py index 3907bd2f4..df7cd9f54 100644 --- a/python/quantum-pecos/src/pecos/qeccs/color_488/color_488.py +++ b/python/quantum-pecos/src/pecos/qeccs/color_488/color_488.py @@ -18,6 +18,7 @@ from typing import Any +from pecos.qec.color.geometry import generate_488_layout from pecos.qeccs.color_488.circuit_implementation1 import OneAncillaPerCheck from pecos.qeccs.color_488.gates import GateIdentity, GateInitPlus, GateInitZero from pecos.qeccs.color_488.instructions import ( @@ -153,36 +154,41 @@ def _get_distance(params: dict[str, Any]) -> tuple[int, int, int]: return distance, distance_height, distance_width def _generate_layout(self) -> dict: - """Creates the layout dictionary which describes the location of the qubits in the code.""" + """Creates the layout dictionary which describes the location of the qubits in the code. + + Uses pecos.qec.color.geometry for data qubit layout generation. + """ self.lattice_height = 4 * self.distance - 4 self.lattice_width = 2 * self.distance - 2 - data_ids = self._data_id_iter() - ancilla_ids = self._ancilla_id_iter() self.lattice_dimensions = { "width": self.lattice_width, "height": self.lattice_height, } - # Determine the position of things + # Use pecos.qec for data qubit layout + nodeid2pos, _ = generate_488_layout(self.distance) + + # Add data qubits to layout + for nid, pos in nodeid2pos.items(): + self.layout[nid] = pos + self.position2qudit[pos] = nid + self.qudit_set.add(nid) + self.data_qudit_set.add(nid) + + # Add ancilla qubits (check positions) + ancilla_ids = self._ancilla_id_iter() for y in range(self.lattice_width + 1): for x in range(self.lattice_height + 1): + # Skip positions outside the triangular region if ((x, y) == (x, x + 2) and x % 2 == 1 and y % 8 == 3) or ( (x, y) == (4 * self.distance - y, y) and x % 2 == 1 and y % 8 == 7 ): pass - elif (x, y) > (x, x) or (x, y) > (4 * self.distance - y - 2, y): continue - if x % 2 == 0 and y % 2 == 0: # Data - if (y / 2) % 4 == 1 or (y / 2) % 4 == 2: - if (x / 2) % 4 == 2 or (x / 2) % 4 == 3: - self._add_node(x, y, data_ids) - - elif (x / 2) % 4 == 0 or (x / 2) % 4 == 1: - self._add_node(x, y, data_ids) - + # Ancilla positions if x % 4 == 1 and y % 4 == 3: self._add_node(x, y, ancilla_ids) diff --git a/python/quantum-pecos/src/pecos/qeccs/surface_4444/surface_4444.py b/python/quantum-pecos/src/pecos/qeccs/surface_4444/surface_4444.py index f8bae309d..0f66b26df 100644 --- a/python/quantum-pecos/src/pecos/qeccs/surface_4444/surface_4444.py +++ b/python/quantum-pecos/src/pecos/qeccs/surface_4444/surface_4444.py @@ -22,6 +22,7 @@ from typing import TYPE_CHECKING from pecos.circuit_converters.checks2circuit import Check2Circuits +from pecos.qec.surface.layouts import generate_nonrotated_surface_layout from pecos.qeccs.default_qecc import DefaultQECC from pecos.qeccs.surface_4444.gates import GateIdentity, GateInitPlus, GateInitZero from pecos.qeccs.surface_4444.instructions import ( @@ -207,8 +208,7 @@ def _add_node(self, x: int, y: int, iter_ids: Iterator[int]) -> None: def _generate_layout(self) -> dict: """Creates the layout dictionary which describes the location of the qubits in the code. - :param qudit_ids: - :return: + Uses pecos.qec.surface.layouts for layout generation. """ height = self.height width = self.width @@ -216,28 +216,33 @@ def _generate_layout(self) -> dict: lattice_width = 2 * (width - 1) self.lattice_height = lattice_height self.lattice_width = lattice_width - data_ids = self._data_id_iter() - ancilla_ids = self._ancilla_id_iter() self.lattice_dimensions = { "width": lattice_width, - "height": lattice_width, + "height": lattice_height, } - # Determine the position of things - for y in range(lattice_height + 1): - for x in range(lattice_width + 1): - if (x % 2 == 0 and y % 2 == 0) or (x % 2 == 1 and y % 2 == 1): - # Data - self._add_node(x, y, data_ids) - - elif x % 2 == 1 and y % 2 == 0: - # X ancilla - self._add_node(x, y, ancilla_ids) + # Use pecos.qec for layout generation + data_positions, ancilla_positions, _ = generate_nonrotated_surface_layout( + width, + height, + ) - elif x % 2 == 0 and y % 2 == 1: - # Z ancilla - self._add_node(x, y, ancilla_ids) + # Add data qubits + for nid, pos in enumerate(data_positions): + self.layout[nid] = pos + self.position_to_qubit[pos] = nid + self.qudit_set.add(nid) + self.data_qudit_set.add(nid) + + # Add ancilla qubits + ancilla_start_id = len(data_positions) + for i, pos in enumerate(ancilla_positions): + nid = ancilla_start_id + i + self.layout[nid] = pos + self.position_to_qubit[pos] = nid + self.qudit_set.add(nid) + self.ancilla_qudit_set.add(nid) return self.layout diff --git a/python/quantum-pecos/src/pecos/qeccs/surface_medial_4444/surface_medial_4444.py b/python/quantum-pecos/src/pecos/qeccs/surface_medial_4444/surface_medial_4444.py index dd7b9abc6..10e900bab 100644 --- a/python/quantum-pecos/src/pecos/qeccs/surface_medial_4444/surface_medial_4444.py +++ b/python/quantum-pecos/src/pecos/qeccs/surface_medial_4444/surface_medial_4444.py @@ -11,15 +11,17 @@ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. -"""Medial Surface 4.4.4.4 quantum error correcting code implementation. +"""Rotated Surface 4.4.4.4 quantum error correcting code implementation. -This module provides the Medial Surface code on a 4.4.4.4 lattice structure, -a topological quantum error correcting code with a medial layout. -""" +This module provides the Rotated Surface code on a 4.4.4.4 lattice structure, +a topological quantum error correcting code. The rotated layout is the most +commonly used surface code variant. -from collections.abc import Generator +Note: This is also known as the "medial" surface code in some literature. +""" from pecos.circuit_converters.checks2circuit import Check2Circuits +from pecos.qec.surface.layouts import generate_surface_layout from pecos.qeccs.default_qecc import DefaultQECC from pecos.qeccs.surface_medial_4444.gates import ( GateIdentity, @@ -170,8 +172,7 @@ def _get_distance(self) -> tuple[int, int, int]: def _generate_layout(self) -> dict: """Creates the layout dictionary which describes the location of the qubits in the code. - :param qudit_ids: - :return: + Uses pecos.qec.surface.layouts for rotated surface code layout generation. """ height = self.height width = self.width @@ -179,79 +180,33 @@ def _generate_layout(self) -> dict: lattice_width = 2 * width self.lattice_height = lattice_height self.lattice_width = lattice_width - data_ids = self._data_id_iter() - ancilla_ids = self._ancilla_id_iter() self.lattice_dimensions = { - "width": 2 * width, - "height": 2 * height, + "width": lattice_width, + "height": lattice_height, } - xy_iter = ( - self._rotated_orientaition() if self.rotated else self._norm_orientaition() - ) - - # Determine the position of things - for x, y in xy_iter: - if 0 < x < lattice_width and 0 < y < lattice_height: - # Interior (no digons) - - if x % 2 == 1 and y % 2 == 1: # That is, both coordinates are odd... - # Data - - self._add_node(x, y, data_ids) - - elif x % 2 == 0 and y % 2 == 0: - # Ancilla - - self._add_node(x, y, ancilla_ids) - - elif 0 < x < lattice_width or 0 < y < lattice_height: - # Not the corners or the interior - - if y == 0: - # Top: X checks - - if x != 0 and x % 4 == 0: - self._add_node(x, y, ancilla_ids) - - elif x == 0 and (y - 2) % 4 == 0: - # Left column - # X checks - self._add_node(x, y, ancilla_ids) - - if y == lattice_height: - # Bottom: X checks - - if height % 2 == 0: - if x != 0 and x % 4 == 0: - self._add_node(x, y, ancilla_ids) - - elif (x - 2) % 4 == 0: - self._add_node(x, y, ancilla_ids) - - elif x == lattice_width: - # Right column - # X checks - - if width % 2 == 1: - if y != 0 and y % 4 == 0: - self._add_node(x, y, ancilla_ids) - elif (y - 2) % 4 == 0: - self._add_node(x, y, ancilla_ids) + # Use pecos.qec for layout generation + data_positions, ancilla_positions = generate_surface_layout(width, height) + + # Add data qubits + for nid, pos in enumerate(data_positions): + self.layout[nid] = pos + self.position2qudit[pos] = nid + self.qudit_set.add(nid) + self.data_qudit_set.add(nid) + + # Add ancilla qubits + ancilla_start_id = len(data_positions) + for i, pos in enumerate(ancilla_positions): + nid = ancilla_start_id + i + self.layout[nid] = pos + self.position2qudit[pos] = nid + self.qudit_set.add(nid) + self.ancilla_qudit_set.add(nid) return self.layout - def _norm_orientaition(self) -> Generator[tuple[int, int], None, None]: - for y in range(self.lattice_height + 1): - for x in range(self.lattice_width + 1): - yield x, y - - def _rotated_orientaition(self) -> Generator[tuple[int, int], None, None]: - for x in range(self.lattice_width + 1): - for y in range(self.lattice_height + 1): - yield x, y - def _determine_sides(self) -> dict[str, list]: """Outputs a dictionary that describes the sides of the code. diff --git a/python/quantum-pecos/src/pecos/qeclib/color488/abstract_layout.py b/python/quantum-pecos/src/pecos/qeclib/color488/abstract_layout.py deleted file mode 100644 index fd5f6072e..000000000 --- a/python/quantum-pecos/src/pecos/qeclib/color488/abstract_layout.py +++ /dev/null @@ -1,184 +0,0 @@ -# Copyright 2018 The PECOS Developers -# Copyright 2018 National Technology & Engineering Solutions of Sandia, LLC (NTESS). Under the terms of Contract -# DE-NA0003525 with NTESS, the U.S. Government retains certain rights in this software. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with -# the License.You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the -# specific language governing permissions and limitations under the License. - -"""Abstract layout generation for color 488 quantum error correction codes.""" - -from typing import Any - - -def gen_layout(distance: int) -> tuple[dict[int, tuple[int, int]], list[list[Any]]]: - """Creates an abstract layout which represents the location of the qubits in the code for a fixed 2D geometry.""" - lattice_height = 4 * distance - 4 - lattice_width = 2 * distance - 2 - pos_qubits = [] - pos_checks = [] - - for y in range(lattice_width + 1): - for x in range(lattice_height + 1): - if ((x, y) == (x, x + 2) and x % 2 == 1 and y % 8 == 3) or ( - (x, y) == (4 * distance - y, y) and x % 2 == 1 and y % 8 == 7 - ): - pass - - elif (x, y) > (x, x) or (x, y) > (4 * distance - y - 2, y): - continue - - if x % 2 == 0 and y % 2 == 0: - if (y / 2) % 4 == 1 or (y / 2) % 4 == 2: - if (x / 2) % 4 == 2 or (x / 2) % 4 == 3: - pos_qubits.append((x, y)) - - elif (x / 2) % 4 == 0 or (x / 2) % 4 == 1: - pos_qubits.append((x, y)) - - if x % 4 == 1 and y % 4 == 3: - pos_checks.append((x, y)) - - if y == 0 and x % 8 == 5: - pos_checks.append((x, y)) - - pos_qubits = sorted(pos_qubits, key=lambda point: (-point[1], point[0])) - pos_checks = sorted(pos_checks, key=lambda point: (-point[1], point[0])) - nodeid2pos = {i: pos_qubits[i] for i in range(len(pos_qubits))} - pos2nodeid = {v: k for k, v in nodeid2pos.items()} - - polygons = [] - for x, y in pos_checks: - if square := found_square(x, y, pos2nodeid): - polygons.append(square) - elif y == 0 and (gon := found_bottomgon(x, y, pos2nodeid)): - polygons.append(gon) - elif octo := found_octogon(x, y, pos2nodeid): - polygons.append(octo) - else: - pass - - return nodeid2pos, polygons - - -def get_boundaries( - nodeid2pos: dict[int, tuple[int, int]], -) -> tuple[list[int], list[int], list[int]]: - """Determines the nodes that lie along the left, right, and bottom boundaries. - - Returns: - Three lists: 1) nodes of the left, 2) bottom, and 3) right boundaries of a triangular 4.8.8 color code. - """ - # TODO: do this... - - -def found_square( - x: int, - y: int, - pos2nodeid: dict[tuple[int, int], int], -) -> list[Any] | bool: - """Check if a square stabilizer can be formed at the given position. - - Args: - x: X coordinate of the check position. - y: Y coordinate of the check position. - pos2nodeid: Mapping from positions to node IDs. - - Returns: - List of node IDs forming the square plus color, or False if square cannot be formed. - """ - square = [(x - 1, y + 1), (x - 1, y - 1), (x + 1, y - 1), (x + 1, y + 1)] - square_ids = [] - for coord in square: - nid = pos2nodeid.get(coord) - if nid is None: - return False - square_ids.append(nid) - - square_ids.append("red") - - return square_ids - - -def found_octogon( - x: int, - y: int, - pos2nodeid: dict[tuple[int, int], int], -) -> list[Any] | bool: - """Check if an octagon stabilizer can be formed at the given position. - - Args: - x: X coordinate of the check position. - y: Y coordinate of the check position. - pos2nodeid: Mapping from positions to node IDs. - - Returns: - List of node IDs forming the octagon plus color, or False if octagon cannot be formed. - """ - octogon = [ - (x - 1, y + 3), - (x - 3, y + 1), - (x - 3, y - 1), - (x - 1, y - 3), - (x + 1, y - 3), - (x + 3, y - 1), - (x + 3, y + 1), - (x + 1, y + 3), - ] - octo_ids = [] - - for coord in octogon: - nid = pos2nodeid.get(coord) - if nid is not None: - octo_ids.append(nid) - - if not octo_ids: - return False - - if (x - 1) // 4 % 2: - octo_ids.append("green") - else: - octo_ids.append("blue") - - return octo_ids - - -def found_bottomgon( - x: int, - y: int, - pos2nodeid: dict[tuple[int, int], int], -) -> list[Any] | bool: - """Check if a bottom boundary stabilizer can be formed at the given position. - - Args: - x: X coordinate of the check position. - y: Y coordinate of the check position. - pos2nodeid: Mapping from positions to node IDs. - - Returns: - List of node IDs forming the bottom boundary stabilizer plus color, or False if it cannot be formed. - """ - coords = [ - (x - 1, y + 2), - (x - 3, y), - (x + 3, y), - (x + 1, y + 2), - ] - found_ids = [] - for coord in coords: - nid = pos2nodeid.get(coord) - if nid is None: - return False - found_ids.append(nid) - - if (x - 1) // 4 % 2: - found_ids.append("green") - else: - found_ids.append("blue") - - return found_ids diff --git a/python/quantum-pecos/src/pecos/qeclib/surface/layouts/square_lattice.py b/python/quantum-pecos/src/pecos/qeclib/surface/layouts/square_lattice.py deleted file mode 100644 index 14aa5b0de..000000000 --- a/python/quantum-pecos/src/pecos/qeclib/surface/layouts/square_lattice.py +++ /dev/null @@ -1,84 +0,0 @@ -# Copyright 2018 The PECOS Developers -# Copyright 2018 National Technology & Engineering Solutions of Sandia, LLC (NTESS). Under the terms of Contract -# DE-NA0003525 with NTESS, the U.S. Government retains certain rights in this software. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with -# the License.You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the -# specific language governing permissions and limitations under the License. - -"""Square lattice layout generation for surface codes.""" - - -def gen_layout( - width: int, - height: int, -) -> tuple[list[tuple[int, int]], list[tuple[int, int]], list[list[tuple[int, int]]]]: - """Generate rectangular surface code patch layout for a 4.4.4.4 lattice. - - Args: - width: Width of the patch in logical qubits. - height: Height of the patch in logical qubits. - - Returns: - A tuple containing: - - nodes: List of (x, y) coordinates for data qubits. - - dual_nodes: List of (x, y) coordinates for ancilla qubits. - - polygons: List of polygons representing stabilizer checks. - """ - lattice_height = 2 * (height - 1) - lattice_width = 2 * (width - 1) - - nodes = [] - dual_nodes = [] - polygons_0 = [] - polygons_1 = [] - - # Determine the position of things - for y in range(lattice_height + 1): - for x in range(lattice_width + 1): - if (x % 2 == 0 and y % 2 == 0) or (x % 2 == 1 and y % 2 == 1): - # Data - nodes.append((x, y)) - - elif x % 2 == 1 and y % 2 == 0: - # X ancilla - dual_nodes.append((x, y)) - - poly = [] - if y != lattice_height: - poly.append((x, y + 1)) - if x != 0: - poly.append((x - 1, y)) - if y != 0: - poly.append((x, y - 1)) - if x != lattice_width: - poly.append((x + 1, y)) - - polygons_0.append(poly) - - elif x % 2 == 0 and y % 2 == 1: - # Z ancilla - dual_nodes.append((x, y)) - - poly = [] - if y != lattice_height: - poly.append((x, y + 1)) - if x != 0: - poly.append((x - 1, y)) - if y != 0: - poly.append((x, y - 1)) - if x != lattice_width: - poly.append((x + 1, y)) - - polygons_0.append(poly) - - polygons = [] - polygons.extend(polygons_0) - polygons.extend(polygons_1) - - return nodes, dual_nodes, polygons diff --git a/python/quantum-pecos/src/pecos/slr/__init__.py b/python/quantum-pecos/src/pecos/slr/__init__.py index ce387c3a4..054c7492c 100644 --- a/python/quantum-pecos/src/pecos/slr/__init__.py +++ b/python/quantum-pecos/src/pecos/slr/__init__.py @@ -9,6 +9,8 @@ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. +# QEC library (moved from pecos.qeclib) +from pecos.slr import qeclib from pecos.slr.block import Block from pecos.slr.cond_block import If, Repeat from pecos.slr.loop_block import For, While @@ -45,4 +47,6 @@ "SlrConverter", "Vars", "While", + # QEC library + "qeclib", ] diff --git a/python/quantum-pecos/src/pecos/slr/converters/from_quantum_circuit.py b/python/quantum-pecos/src/pecos/slr/converters/from_quantum_circuit.py index d465f7799..42736a0c7 100644 --- a/python/quantum-pecos/src/pecos/slr/converters/from_quantum_circuit.py +++ b/python/quantum-pecos/src/pecos/slr/converters/from_quantum_circuit.py @@ -15,8 +15,8 @@ from typing import TYPE_CHECKING -from pecos.qeclib import qubit from pecos.slr import Barrier, Comment, CReg, Main, Parallel, QReg +from pecos.slr.qeclib import qubit if TYPE_CHECKING: from pecos.circuits.quantum_circuit import QuantumCircuit diff --git a/python/quantum-pecos/src/pecos/slr/converters/from_stim.py b/python/quantum-pecos/src/pecos/slr/converters/from_stim.py index 335605e1c..edc1127ff 100644 --- a/python/quantum-pecos/src/pecos/slr/converters/from_stim.py +++ b/python/quantum-pecos/src/pecos/slr/converters/from_stim.py @@ -15,8 +15,8 @@ from typing import TYPE_CHECKING -from pecos.qeclib import qubit from pecos.slr import Comment, CReg, Main, QReg, Repeat +from pecos.slr.qeclib import qubit if TYPE_CHECKING: import stim diff --git a/python/quantum-pecos/src/pecos/slr/gen_codes/gen_qir.py b/python/quantum-pecos/src/pecos/slr/gen_codes/gen_qir.py index 01f259e28..d94fb58e3 100644 --- a/python/quantum-pecos/src/pecos/slr/gen_codes/gen_qir.py +++ b/python/quantum-pecos/src/pecos/slr/gen_codes/gen_qir.py @@ -18,7 +18,6 @@ from pecos_rslib.llvm import binding, ir import pecos as pc -from pecos.qeclib.qubit import qgate_base from pecos.slr import Block, If, Repeat from pecos.slr.cops import ( NEG, @@ -30,6 +29,7 @@ from pecos.slr.gen_codes.generator import Generator from pecos.slr.gen_codes.qir_gate_mapping import QIRGateMetadata from pecos.slr.misc import Barrier, Comment, Permute +from pecos.slr.qeclib.qubit import qgate_base from pecos.slr.vars import Bit, CReg, QReg, Qubit, Reg, Vars if TYPE_CHECKING: diff --git a/python/quantum-pecos/src/pecos/slr/gen_codes/qir_gate_mapping.py b/python/quantum-pecos/src/pecos/slr/gen_codes/qir_gate_mapping.py index 0599eea5d..d0394a8de 100644 --- a/python/quantum-pecos/src/pecos/slr/gen_codes/qir_gate_mapping.py +++ b/python/quantum-pecos/src/pecos/slr/gen_codes/qir_gate_mapping.py @@ -15,10 +15,10 @@ from typing import TYPE_CHECKING import pecos as pc -from pecos.qeclib import qubit as q +from pecos.slr.qeclib import qubit as q if TYPE_CHECKING: - from pecos.qeclib.qubit.qgate_base import QGate + from pecos.slr.qeclib.qubit.qgate_base import QGate @dataclass diff --git a/python/quantum-pecos/src/pecos/qeclib/__init__.py b/python/quantum-pecos/src/pecos/slr/qeclib/__init__.py similarity index 100% rename from python/quantum-pecos/src/pecos/qeclib/__init__.py rename to python/quantum-pecos/src/pecos/slr/qeclib/__init__.py diff --git a/python/quantum-pecos/src/pecos/qeclib/color488/__init__.py b/python/quantum-pecos/src/pecos/slr/qeclib/color488/__init__.py similarity index 93% rename from python/quantum-pecos/src/pecos/qeclib/color488/__init__.py rename to python/quantum-pecos/src/pecos/slr/qeclib/color488/__init__.py index c7c71dc7c..541e9c4b2 100644 --- a/python/quantum-pecos/src/pecos/qeclib/color488/__init__.py +++ b/python/quantum-pecos/src/pecos/slr/qeclib/color488/__init__.py @@ -17,7 +17,7 @@ from enum import Enum -from pecos.qeclib.color488.color488_class import Color488Patch +from pecos.slr.qeclib.color488.color488_class import Color488Patch class Language(Enum): diff --git a/python/quantum-pecos/src/pecos/qeclib/color488/color488.py b/python/quantum-pecos/src/pecos/slr/qeclib/color488/color488.py similarity index 78% rename from python/quantum-pecos/src/pecos/qeclib/color488/color488.py rename to python/quantum-pecos/src/pecos/slr/qeclib/color488/color488.py index 1e58302d7..84e9cbe73 100644 --- a/python/quantum-pecos/src/pecos/qeclib/color488/color488.py +++ b/python/quantum-pecos/src/pecos/slr/qeclib/color488/color488.py @@ -13,11 +13,14 @@ from typing import Any -from pecos.qeclib.color488.abstract_layout import gen_layout, get_boundaries +from pecos.qec.color.geometry import generate_488_layout class Color488: - """Implementation of the Color 488 quantum error correction code.""" + """Implementation of the Color 488 quantum error correction code. + + This is a thin wrapper around pecos.qec.color geometry for use in SLR code. + """ def __init__(self, distance: int) -> None: """Initialize a Color 488 code instance. @@ -39,18 +42,9 @@ def get_layout(self) -> tuple[dict[int, tuple[int, int]], list[list[Any]]]: - polygons: List of stabilizer polygons. """ if self._layout_cache is None: - self._layout_cache = gen_layout(self.distance) + self._layout_cache = generate_488_layout(self.distance) return self._layout_cache - def get_boundaries(self) -> tuple[list[int], list[int], list[int]]: - """Get the boundaries of the color 488 code layout. - - Returns: - A tuple containing the left, bottom, and right boundary node lists. - """ - nodeid2pos, _ = self.get_layout() - return get_boundaries(nodeid2pos) - def num_data_qubits(self) -> int: """Get the number of data qubits in the color 488 code. diff --git a/python/quantum-pecos/src/pecos/qeclib/color488/color488_class.py b/python/quantum-pecos/src/pecos/slr/qeclib/color488/color488_class.py similarity index 91% rename from python/quantum-pecos/src/pecos/qeclib/color488/color488_class.py rename to python/quantum-pecos/src/pecos/slr/qeclib/color488/color488_class.py index fdd7a8435..b89ffe09b 100644 --- a/python/quantum-pecos/src/pecos/qeclib/color488/color488_class.py +++ b/python/quantum-pecos/src/pecos/slr/qeclib/color488/color488_class.py @@ -5,14 +5,14 @@ if TYPE_CHECKING: import matplotlib.pyplot as plt -from pecos.qeclib import qubit as qb -from pecos.qeclib.color488.color488 import Color488 -from pecos.qeclib.color488.gates_sq import hadamards, sqrt_paulis -from pecos.qeclib.color488.gates_tq import transversal_tq -from pecos.qeclib.color488.meas.destructive_meas import MeasureZ, SynMeasProcessing -from pecos.qeclib.color488.plot_layout import plot_layout -from pecos.qeclib.color488.syn_extract.bare import SynExtractBareParallel from pecos.slr import Bit, Block, CReg, QReg, Vars +from pecos.slr.qeclib import qubit as qb +from pecos.slr.qeclib.color488.color488 import Color488 +from pecos.slr.qeclib.color488.gates_sq import hadamards, sqrt_paulis +from pecos.slr.qeclib.color488.gates_tq import transversal_tq +from pecos.slr.qeclib.color488.meas.destructive_meas import MeasureZ, SynMeasProcessing +from pecos.slr.qeclib.color488.plot_layout import plot_layout +from pecos.slr.qeclib.color488.syn_extract.bare import SynExtractBareParallel class Color488Patch(Vars): diff --git a/python/quantum-pecos/src/pecos/qeclib/color488/gates_sq/__init__.py b/python/quantum-pecos/src/pecos/slr/qeclib/color488/gates_sq/__init__.py similarity index 96% rename from python/quantum-pecos/src/pecos/qeclib/color488/gates_sq/__init__.py rename to python/quantum-pecos/src/pecos/slr/qeclib/color488/gates_sq/__init__.py index 7d5b81a4f..aa361d937 100644 --- a/python/quantum-pecos/src/pecos/qeclib/color488/gates_sq/__init__.py +++ b/python/quantum-pecos/src/pecos/slr/qeclib/color488/gates_sq/__init__.py @@ -15,8 +15,8 @@ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. -from pecos.qeclib import qubit as qb from pecos.slr import Block, Comment, QReg +from pecos.slr.qeclib import qubit as qb class H(Block): diff --git a/python/quantum-pecos/src/pecos/qeclib/color488/gates_sq/hadamards.py b/python/quantum-pecos/src/pecos/slr/qeclib/color488/gates_sq/hadamards.py similarity index 96% rename from python/quantum-pecos/src/pecos/qeclib/color488/gates_sq/hadamards.py rename to python/quantum-pecos/src/pecos/slr/qeclib/color488/gates_sq/hadamards.py index 4acc869f4..606d15f67 100644 --- a/python/quantum-pecos/src/pecos/qeclib/color488/gates_sq/hadamards.py +++ b/python/quantum-pecos/src/pecos/slr/qeclib/color488/gates_sq/hadamards.py @@ -15,8 +15,8 @@ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. -from pecos.qeclib import qubit as qb from pecos.slr import Block, QReg +from pecos.slr.qeclib import qubit as qb class H(Block): diff --git a/python/quantum-pecos/src/pecos/qeclib/color488/gates_sq/sqrt_paulis.py b/python/quantum-pecos/src/pecos/slr/qeclib/color488/gates_sq/sqrt_paulis.py similarity index 98% rename from python/quantum-pecos/src/pecos/qeclib/color488/gates_sq/sqrt_paulis.py rename to python/quantum-pecos/src/pecos/slr/qeclib/color488/gates_sq/sqrt_paulis.py index a56be39df..b59eeae7a 100644 --- a/python/quantum-pecos/src/pecos/qeclib/color488/gates_sq/sqrt_paulis.py +++ b/python/quantum-pecos/src/pecos/slr/qeclib/color488/gates_sq/sqrt_paulis.py @@ -15,8 +15,8 @@ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. -from pecos.qeclib import qubit as qb from pecos.slr import Block, QReg +from pecos.slr.qeclib import qubit as qb class SZ(Block): diff --git a/python/quantum-pecos/src/pecos/qeclib/color488/gates_tq/__init__.py b/python/quantum-pecos/src/pecos/slr/qeclib/color488/gates_tq/__init__.py similarity index 100% rename from python/quantum-pecos/src/pecos/qeclib/color488/gates_tq/__init__.py rename to python/quantum-pecos/src/pecos/slr/qeclib/color488/gates_tq/__init__.py diff --git a/python/quantum-pecos/src/pecos/qeclib/color488/gates_tq/transversal_tq.py b/python/quantum-pecos/src/pecos/slr/qeclib/color488/gates_tq/transversal_tq.py similarity index 100% rename from python/quantum-pecos/src/pecos/qeclib/color488/gates_tq/transversal_tq.py rename to python/quantum-pecos/src/pecos/slr/qeclib/color488/gates_tq/transversal_tq.py diff --git a/python/quantum-pecos/src/pecos/qeclib/color488/meas/__init__.py b/python/quantum-pecos/src/pecos/slr/qeclib/color488/meas/__init__.py similarity index 100% rename from python/quantum-pecos/src/pecos/qeclib/color488/meas/__init__.py rename to python/quantum-pecos/src/pecos/slr/qeclib/color488/meas/__init__.py diff --git a/python/quantum-pecos/src/pecos/qeclib/color488/meas/destructive_meas.py b/python/quantum-pecos/src/pecos/slr/qeclib/color488/meas/destructive_meas.py similarity index 98% rename from python/quantum-pecos/src/pecos/qeclib/color488/meas/destructive_meas.py rename to python/quantum-pecos/src/pecos/slr/qeclib/color488/meas/destructive_meas.py index 12b83c960..071afa1d7 100644 --- a/python/quantum-pecos/src/pecos/qeclib/color488/meas/destructive_meas.py +++ b/python/quantum-pecos/src/pecos/slr/qeclib/color488/meas/destructive_meas.py @@ -1,7 +1,7 @@ """Module containing destructive measurement operations for color 488 codes.""" -from pecos.qeclib import qubit as qb from pecos.slr import Bit, Block, CReg, QReg +from pecos.slr.qeclib import qubit as qb class MeasureZ(Block): diff --git a/python/quantum-pecos/src/pecos/qeclib/color488/plot_layout.py b/python/quantum-pecos/src/pecos/slr/qeclib/color488/plot_layout.py similarity index 97% rename from python/quantum-pecos/src/pecos/qeclib/color488/plot_layout.py rename to python/quantum-pecos/src/pecos/slr/qeclib/color488/plot_layout.py index aba447701..9d90eba16 100644 --- a/python/quantum-pecos/src/pecos/qeclib/color488/plot_layout.py +++ b/python/quantum-pecos/src/pecos/slr/qeclib/color488/plot_layout.py @@ -18,7 +18,7 @@ if TYPE_CHECKING: - from pecos.qeclib.color488 import Color488 + from pecos.slr.qeclib.color488 import Color488 def plot_layout( @@ -37,7 +37,7 @@ def plot_layout( Returns: The matplotlib pyplot module with the plot rendered. """ - import matplotlib.pyplot as plt + import matplotlib.pyplot as plt # noqa: PLC0415 positions, polygons = color488.get_layout() diff --git a/python/quantum-pecos/src/pecos/qeclib/color488/syn_extract/__init__.py b/python/quantum-pecos/src/pecos/slr/qeclib/color488/syn_extract/__init__.py similarity index 100% rename from python/quantum-pecos/src/pecos/qeclib/color488/syn_extract/__init__.py rename to python/quantum-pecos/src/pecos/slr/qeclib/color488/syn_extract/__init__.py diff --git a/python/quantum-pecos/src/pecos/qeclib/color488/syn_extract/bare.py b/python/quantum-pecos/src/pecos/slr/qeclib/color488/syn_extract/bare.py similarity index 98% rename from python/quantum-pecos/src/pecos/qeclib/color488/syn_extract/bare.py rename to python/quantum-pecos/src/pecos/slr/qeclib/color488/syn_extract/bare.py index 9c01bc1f3..35f9ecce7 100644 --- a/python/quantum-pecos/src/pecos/qeclib/color488/syn_extract/bare.py +++ b/python/quantum-pecos/src/pecos/slr/qeclib/color488/syn_extract/bare.py @@ -4,8 +4,8 @@ from typing import Any import pecos as pc -from pecos.qeclib.generic.check import Check from pecos.slr import Block, Comment, CReg, Parallel, QReg +from pecos.slr.qeclib.generic.check import Check def poly2qubits(poly: list[Any], data: QReg) -> list[Any]: diff --git a/python/quantum-pecos/src/pecos/qeclib/generic/__init__.py b/python/quantum-pecos/src/pecos/slr/qeclib/generic/__init__.py similarity index 100% rename from python/quantum-pecos/src/pecos/qeclib/generic/__init__.py rename to python/quantum-pecos/src/pecos/slr/qeclib/generic/__init__.py diff --git a/python/quantum-pecos/src/pecos/qeclib/generic/check.py b/python/quantum-pecos/src/pecos/slr/qeclib/generic/check.py similarity index 97% rename from python/quantum-pecos/src/pecos/qeclib/generic/check.py rename to python/quantum-pecos/src/pecos/slr/qeclib/generic/check.py index fe9b7694a..6c747f6ba 100644 --- a/python/quantum-pecos/src/pecos/qeclib/generic/check.py +++ b/python/quantum-pecos/src/pecos/slr/qeclib/generic/check.py @@ -20,12 +20,12 @@ from typing import TYPE_CHECKING -from pecos.qeclib.qubit import CX, CY, CZ, H, Measure, Prep from pecos.slr import Barrier, Block, Comment +from pecos.slr.qeclib.qubit import CX, CY, CZ, H, Measure, Prep if TYPE_CHECKING: - from pecos.qeclib.qubit.qgate_base import QGate from pecos.slr import Bit, Qubit + from pecos.slr.qeclib.qubit.qgate_base import QGate class Check(Block): diff --git a/python/quantum-pecos/src/pecos/qeclib/generic/check_1flag.py b/python/quantum-pecos/src/pecos/slr/qeclib/generic/check_1flag.py similarity index 97% rename from python/quantum-pecos/src/pecos/qeclib/generic/check_1flag.py rename to python/quantum-pecos/src/pecos/slr/qeclib/generic/check_1flag.py index 85897fb4b..1118c68cc 100644 --- a/python/quantum-pecos/src/pecos/qeclib/generic/check_1flag.py +++ b/python/quantum-pecos/src/pecos/slr/qeclib/generic/check_1flag.py @@ -20,12 +20,12 @@ from typing import TYPE_CHECKING -from pecos.qeclib.qubit import CH, CX, CY, CZ, H, Measure, Prep from pecos.slr import Barrier, Block, Comment +from pecos.slr.qeclib.qubit import CH, CX, CY, CZ, H, Measure, Prep if TYPE_CHECKING: - from pecos.qeclib.qubit.qgate_base import QGate from pecos.slr import Bit, Qubit + from pecos.slr.qeclib.qubit.qgate_base import QGate class Check1Flag(Block): diff --git a/python/quantum-pecos/src/pecos/qeclib/generic/transversal.py b/python/quantum-pecos/src/pecos/slr/qeclib/generic/transversal.py similarity index 100% rename from python/quantum-pecos/src/pecos/qeclib/generic/transversal.py rename to python/quantum-pecos/src/pecos/slr/qeclib/generic/transversal.py diff --git a/python/quantum-pecos/src/pecos/qeclib/qubit/__init__.py b/python/quantum-pecos/src/pecos/slr/qeclib/qubit/__init__.py similarity index 68% rename from python/quantum-pecos/src/pecos/qeclib/qubit/__init__.py rename to python/quantum-pecos/src/pecos/slr/qeclib/qubit/__init__.py index 8ee828f21..69bf33721 100644 --- a/python/quantum-pecos/src/pecos/qeclib/qubit/__init__.py +++ b/python/quantum-pecos/src/pecos/slr/qeclib/qubit/__init__.py @@ -15,15 +15,15 @@ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. -from pecos.qeclib.qubit.measures import Measure -from pecos.qeclib.qubit.preps import Prep -from pecos.qeclib.qubit.rots import RX, RY, RZ, RZZ -from pecos.qeclib.qubit.sq_face_rots import F4, F, F4dg, Fdg -from pecos.qeclib.qubit.sq_hadamards import H -from pecos.qeclib.qubit.sq_noncliffords import T, Tdg -from pecos.qeclib.qubit.sq_paulis import X, Y, Z -from pecos.qeclib.qubit.sq_sqrt_paulis import SX, SY, SZ, SXdg, SYdg, SZdg -from pecos.qeclib.qubit.tq_cliffords import ( +from pecos.slr.qeclib.qubit.measures import Measure +from pecos.slr.qeclib.qubit.preps import Prep +from pecos.slr.qeclib.qubit.rots import RX, RY, RZ, RZZ +from pecos.slr.qeclib.qubit.sq_face_rots import F4, F, F4dg, Fdg +from pecos.slr.qeclib.qubit.sq_hadamards import H +from pecos.slr.qeclib.qubit.sq_noncliffords import T, Tdg +from pecos.slr.qeclib.qubit.sq_paulis import X, Y, Z +from pecos.slr.qeclib.qubit.sq_sqrt_paulis import SX, SY, SZ, SXdg, SYdg, SZdg +from pecos.slr.qeclib.qubit.tq_cliffords import ( CX, CY, CZ, @@ -34,7 +34,7 @@ SYYdg, SZZdg, ) -from pecos.qeclib.qubit.tq_noncliffords import CH +from pecos.slr.qeclib.qubit.tq_noncliffords import CH __all__ = [ "CH", diff --git a/python/quantum-pecos/src/pecos/qeclib/qubit/measures.py b/python/quantum-pecos/src/pecos/slr/qeclib/qubit/measures.py similarity index 96% rename from python/quantum-pecos/src/pecos/qeclib/qubit/measures.py rename to python/quantum-pecos/src/pecos/slr/qeclib/qubit/measures.py index 13dc81f34..5205abea8 100644 --- a/python/quantum-pecos/src/pecos/qeclib/qubit/measures.py +++ b/python/quantum-pecos/src/pecos/slr/qeclib/qubit/measures.py @@ -20,7 +20,7 @@ from typing import TYPE_CHECKING -from pecos.qeclib.qubit.qgate_base import QGate +from pecos.slr.qeclib.qubit.qgate_base import QGate if TYPE_CHECKING: from pecos.slr import Bit, Qubit diff --git a/python/quantum-pecos/src/pecos/qeclib/qubit/preps.py b/python/quantum-pecos/src/pecos/slr/qeclib/qubit/preps.py similarity index 94% rename from python/quantum-pecos/src/pecos/qeclib/qubit/preps.py rename to python/quantum-pecos/src/pecos/slr/qeclib/qubit/preps.py index 2298f0470..614173775 100644 --- a/python/quantum-pecos/src/pecos/qeclib/qubit/preps.py +++ b/python/quantum-pecos/src/pecos/slr/qeclib/qubit/preps.py @@ -16,7 +16,7 @@ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. -from pecos.qeclib.qubit.qgate_base import QGate +from pecos.slr.qeclib.qubit.qgate_base import QGate class Prep(QGate): diff --git a/python/quantum-pecos/src/pecos/qeclib/qubit/qgate_base.py b/python/quantum-pecos/src/pecos/slr/qeclib/qubit/qgate_base.py similarity index 100% rename from python/quantum-pecos/src/pecos/qeclib/qubit/qgate_base.py rename to python/quantum-pecos/src/pecos/slr/qeclib/qubit/qgate_base.py diff --git a/python/quantum-pecos/src/pecos/qeclib/qubit/qubit.py b/python/quantum-pecos/src/pecos/slr/qeclib/qubit/qubit.py similarity index 98% rename from python/quantum-pecos/src/pecos/qeclib/qubit/qubit.py rename to python/quantum-pecos/src/pecos/slr/qeclib/qubit/qubit.py index e4d09d1af..75faad679 100644 --- a/python/quantum-pecos/src/pecos/qeclib/qubit/qubit.py +++ b/python/quantum-pecos/src/pecos/slr/qeclib/qubit/qubit.py @@ -4,7 +4,7 @@ from typing import TYPE_CHECKING -from pecos.qeclib.qubit import ( +from pecos.slr.qeclib.qubit import ( measures, preps, sq_hadamards, diff --git a/python/quantum-pecos/src/pecos/qeclib/qubit/rots.py b/python/quantum-pecos/src/pecos/slr/qeclib/qubit/rots.py similarity index 96% rename from python/quantum-pecos/src/pecos/qeclib/qubit/rots.py rename to python/quantum-pecos/src/pecos/slr/qeclib/qubit/rots.py index 80b61d205..073fae61c 100644 --- a/python/quantum-pecos/src/pecos/qeclib/qubit/rots.py +++ b/python/quantum-pecos/src/pecos/slr/qeclib/qubit/rots.py @@ -16,7 +16,7 @@ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. -from pecos.qeclib.qubit.qgate_base import QGate, TQGate +from pecos.slr.qeclib.qubit.qgate_base import QGate, TQGate class RXGate(QGate): diff --git a/python/quantum-pecos/src/pecos/qeclib/qubit/sq_face_rots.py b/python/quantum-pecos/src/pecos/slr/qeclib/qubit/sq_face_rots.py similarity index 96% rename from python/quantum-pecos/src/pecos/qeclib/qubit/sq_face_rots.py rename to python/quantum-pecos/src/pecos/slr/qeclib/qubit/sq_face_rots.py index e6545c725..6d7327646 100644 --- a/python/quantum-pecos/src/pecos/qeclib/qubit/sq_face_rots.py +++ b/python/quantum-pecos/src/pecos/slr/qeclib/qubit/sq_face_rots.py @@ -15,7 +15,7 @@ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. -from pecos.qeclib.qubit.qgate_base import QGate +from pecos.slr.qeclib.qubit.qgate_base import QGate class F(QGate): diff --git a/python/quantum-pecos/src/pecos/qeclib/qubit/sq_hadamards.py b/python/quantum-pecos/src/pecos/slr/qeclib/qubit/sq_hadamards.py similarity index 94% rename from python/quantum-pecos/src/pecos/qeclib/qubit/sq_hadamards.py rename to python/quantum-pecos/src/pecos/slr/qeclib/qubit/sq_hadamards.py index a72e29bb7..2b11db62c 100644 --- a/python/quantum-pecos/src/pecos/qeclib/qubit/sq_hadamards.py +++ b/python/quantum-pecos/src/pecos/slr/qeclib/qubit/sq_hadamards.py @@ -16,7 +16,7 @@ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. -from pecos.qeclib.qubit.qgate_base import QGate +from pecos.slr.qeclib.qubit.qgate_base import QGate class H(QGate): diff --git a/python/quantum-pecos/src/pecos/qeclib/qubit/sq_noncliffords.py b/python/quantum-pecos/src/pecos/slr/qeclib/qubit/sq_noncliffords.py similarity index 95% rename from python/quantum-pecos/src/pecos/qeclib/qubit/sq_noncliffords.py rename to python/quantum-pecos/src/pecos/slr/qeclib/qubit/sq_noncliffords.py index 07f92f02f..ab90a7fb3 100644 --- a/python/quantum-pecos/src/pecos/qeclib/qubit/sq_noncliffords.py +++ b/python/quantum-pecos/src/pecos/slr/qeclib/qubit/sq_noncliffords.py @@ -16,7 +16,7 @@ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. -from pecos.qeclib.qubit.qgate_base import QGate +from pecos.slr.qeclib.qubit.qgate_base import QGate class T(QGate): diff --git a/python/quantum-pecos/src/pecos/qeclib/qubit/sq_paulis.py b/python/quantum-pecos/src/pecos/slr/qeclib/qubit/sq_paulis.py similarity index 96% rename from python/quantum-pecos/src/pecos/qeclib/qubit/sq_paulis.py rename to python/quantum-pecos/src/pecos/slr/qeclib/qubit/sq_paulis.py index 5ae4bf4c2..6be89ce69 100644 --- a/python/quantum-pecos/src/pecos/qeclib/qubit/sq_paulis.py +++ b/python/quantum-pecos/src/pecos/slr/qeclib/qubit/sq_paulis.py @@ -17,7 +17,7 @@ # specific language governing permissions and limitations under the License. import pecos as pc -from pecos.qeclib.qubit.qgate_base import QGate +from pecos.slr.qeclib.qubit.qgate_base import QGate class X(QGate): diff --git a/python/quantum-pecos/src/pecos/qeclib/qubit/sq_sqrt_paulis.py b/python/quantum-pecos/src/pecos/slr/qeclib/qubit/sq_sqrt_paulis.py similarity index 97% rename from python/quantum-pecos/src/pecos/qeclib/qubit/sq_sqrt_paulis.py rename to python/quantum-pecos/src/pecos/slr/qeclib/qubit/sq_sqrt_paulis.py index 057be3969..c8c811ffa 100644 --- a/python/quantum-pecos/src/pecos/qeclib/qubit/sq_sqrt_paulis.py +++ b/python/quantum-pecos/src/pecos/slr/qeclib/qubit/sq_sqrt_paulis.py @@ -16,7 +16,7 @@ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. -from pecos.qeclib.qubit.qgate_base import QGate +from pecos.slr.qeclib.qubit.qgate_base import QGate class SX(QGate): diff --git a/python/quantum-pecos/src/pecos/qeclib/qubit/tq_cliffords.py b/python/quantum-pecos/src/pecos/slr/qeclib/qubit/tq_cliffords.py similarity index 97% rename from python/quantum-pecos/src/pecos/qeclib/qubit/tq_cliffords.py rename to python/quantum-pecos/src/pecos/slr/qeclib/qubit/tq_cliffords.py index ff9ff16df..06ac50e88 100644 --- a/python/quantum-pecos/src/pecos/qeclib/qubit/tq_cliffords.py +++ b/python/quantum-pecos/src/pecos/slr/qeclib/qubit/tq_cliffords.py @@ -16,7 +16,7 @@ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. -from pecos.qeclib.qubit.qgate_base import TQGate +from pecos.slr.qeclib.qubit.qgate_base import TQGate class CX(TQGate): diff --git a/python/quantum-pecos/src/pecos/qeclib/qubit/tq_noncliffords.py b/python/quantum-pecos/src/pecos/slr/qeclib/qubit/tq_noncliffords.py similarity index 94% rename from python/quantum-pecos/src/pecos/qeclib/qubit/tq_noncliffords.py rename to python/quantum-pecos/src/pecos/slr/qeclib/qubit/tq_noncliffords.py index 94ce374be..ebaee2473 100644 --- a/python/quantum-pecos/src/pecos/qeclib/qubit/tq_noncliffords.py +++ b/python/quantum-pecos/src/pecos/slr/qeclib/qubit/tq_noncliffords.py @@ -16,7 +16,7 @@ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. -from pecos.qeclib.qubit.qgate_base import TQGate +from pecos.slr.qeclib.qubit.qgate_base import TQGate class CH(TQGate): diff --git a/python/quantum-pecos/src/pecos/qeclib/steane/__init__.py b/python/quantum-pecos/src/pecos/slr/qeclib/steane/__init__.py similarity index 100% rename from python/quantum-pecos/src/pecos/qeclib/steane/__init__.py rename to python/quantum-pecos/src/pecos/slr/qeclib/steane/__init__.py diff --git a/python/quantum-pecos/src/pecos/qeclib/steane/decoders/__init__.py b/python/quantum-pecos/src/pecos/slr/qeclib/steane/decoders/__init__.py similarity index 100% rename from python/quantum-pecos/src/pecos/qeclib/steane/decoders/__init__.py rename to python/quantum-pecos/src/pecos/slr/qeclib/steane/decoders/__init__.py diff --git a/python/quantum-pecos/src/pecos/qeclib/steane/decoders/lookup.py b/python/quantum-pecos/src/pecos/slr/qeclib/steane/decoders/lookup.py similarity index 99% rename from python/quantum-pecos/src/pecos/qeclib/steane/decoders/lookup.py rename to python/quantum-pecos/src/pecos/slr/qeclib/steane/decoders/lookup.py index 39d0630fc..2f1c3c127 100644 --- a/python/quantum-pecos/src/pecos/qeclib/steane/decoders/lookup.py +++ b/python/quantum-pecos/src/pecos/slr/qeclib/steane/decoders/lookup.py @@ -18,8 +18,8 @@ from typing import TYPE_CHECKING -from pecos.qeclib import qubit from pecos.slr import Block, Comment, If +from pecos.slr.qeclib import qubit if TYPE_CHECKING: from pecos.slr import Bit, CReg, QReg diff --git a/python/quantum-pecos/src/pecos/qeclib/steane/gates_sq/__init__.py b/python/quantum-pecos/src/pecos/slr/qeclib/steane/gates_sq/__init__.py similarity index 100% rename from python/quantum-pecos/src/pecos/qeclib/steane/gates_sq/__init__.py rename to python/quantum-pecos/src/pecos/slr/qeclib/steane/gates_sq/__init__.py diff --git a/python/quantum-pecos/src/pecos/qeclib/steane/gates_sq/face_rots.py b/python/quantum-pecos/src/pecos/slr/qeclib/steane/gates_sq/face_rots.py similarity index 98% rename from python/quantum-pecos/src/pecos/qeclib/steane/gates_sq/face_rots.py rename to python/quantum-pecos/src/pecos/slr/qeclib/steane/gates_sq/face_rots.py index 7f0104b2d..57fd107df 100644 --- a/python/quantum-pecos/src/pecos/qeclib/steane/gates_sq/face_rots.py +++ b/python/quantum-pecos/src/pecos/slr/qeclib/steane/gates_sq/face_rots.py @@ -15,8 +15,8 @@ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. -from pecos.qeclib import qubit from pecos.slr import Block, QReg +from pecos.slr.qeclib import qubit class F(Block): diff --git a/python/quantum-pecos/src/pecos/qeclib/steane/gates_sq/hadamards.py b/python/quantum-pecos/src/pecos/slr/qeclib/steane/gates_sq/hadamards.py similarity index 97% rename from python/quantum-pecos/src/pecos/qeclib/steane/gates_sq/hadamards.py rename to python/quantum-pecos/src/pecos/slr/qeclib/steane/gates_sq/hadamards.py index a32ea4b32..aad20599d 100644 --- a/python/quantum-pecos/src/pecos/qeclib/steane/gates_sq/hadamards.py +++ b/python/quantum-pecos/src/pecos/slr/qeclib/steane/gates_sq/hadamards.py @@ -15,8 +15,8 @@ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. -from pecos.qeclib import qubit from pecos.slr import Block, Comment, QReg +from pecos.slr.qeclib import qubit class H(Block): diff --git a/python/quantum-pecos/src/pecos/qeclib/steane/gates_sq/paulis.py b/python/quantum-pecos/src/pecos/slr/qeclib/steane/gates_sq/paulis.py similarity index 98% rename from python/quantum-pecos/src/pecos/qeclib/steane/gates_sq/paulis.py rename to python/quantum-pecos/src/pecos/slr/qeclib/steane/gates_sq/paulis.py index 9f28afcd2..b34ac9591 100644 --- a/python/quantum-pecos/src/pecos/qeclib/steane/gates_sq/paulis.py +++ b/python/quantum-pecos/src/pecos/slr/qeclib/steane/gates_sq/paulis.py @@ -15,8 +15,8 @@ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. -from pecos.qeclib import qubit from pecos.slr import Block, Comment, QReg +from pecos.slr.qeclib import qubit class X(Block): diff --git a/python/quantum-pecos/src/pecos/qeclib/steane/gates_sq/sqrt_paulis.py b/python/quantum-pecos/src/pecos/slr/qeclib/steane/gates_sq/sqrt_paulis.py similarity index 99% rename from python/quantum-pecos/src/pecos/qeclib/steane/gates_sq/sqrt_paulis.py rename to python/quantum-pecos/src/pecos/slr/qeclib/steane/gates_sq/sqrt_paulis.py index 7e0cba9d4..2e8d91cb7 100644 --- a/python/quantum-pecos/src/pecos/qeclib/steane/gates_sq/sqrt_paulis.py +++ b/python/quantum-pecos/src/pecos/slr/qeclib/steane/gates_sq/sqrt_paulis.py @@ -15,8 +15,8 @@ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. -from pecos.qeclib import qubit from pecos.slr import Block, Comment, QReg +from pecos.slr.qeclib import qubit class SX(Block): diff --git a/python/quantum-pecos/src/pecos/qeclib/steane/gates_tq/__init__.py b/python/quantum-pecos/src/pecos/slr/qeclib/steane/gates_tq/__init__.py similarity index 100% rename from python/quantum-pecos/src/pecos/qeclib/steane/gates_tq/__init__.py rename to python/quantum-pecos/src/pecos/slr/qeclib/steane/gates_tq/__init__.py diff --git a/python/quantum-pecos/src/pecos/qeclib/steane/gates_tq/transversal_tq.py b/python/quantum-pecos/src/pecos/slr/qeclib/steane/gates_tq/transversal_tq.py similarity index 99% rename from python/quantum-pecos/src/pecos/qeclib/steane/gates_tq/transversal_tq.py rename to python/quantum-pecos/src/pecos/slr/qeclib/steane/gates_tq/transversal_tq.py index 745e0003e..6b1ed60b7 100644 --- a/python/quantum-pecos/src/pecos/qeclib/steane/gates_tq/transversal_tq.py +++ b/python/quantum-pecos/src/pecos/slr/qeclib/steane/gates_tq/transversal_tq.py @@ -15,8 +15,8 @@ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. -from pecos.qeclib import qubit from pecos.slr import Barrier, Block, Comment, QReg +from pecos.slr.qeclib import qubit class CX(Block): diff --git a/python/quantum-pecos/src/pecos/qeclib/steane/meas/__init__.py b/python/quantum-pecos/src/pecos/slr/qeclib/steane/meas/__init__.py similarity index 100% rename from python/quantum-pecos/src/pecos/qeclib/steane/meas/__init__.py rename to python/quantum-pecos/src/pecos/slr/qeclib/steane/meas/__init__.py diff --git a/python/quantum-pecos/src/pecos/qeclib/steane/meas/destructive_meas.py b/python/quantum-pecos/src/pecos/slr/qeclib/steane/meas/destructive_meas.py similarity index 99% rename from python/quantum-pecos/src/pecos/qeclib/steane/meas/destructive_meas.py rename to python/quantum-pecos/src/pecos/slr/qeclib/steane/meas/destructive_meas.py index d911ed6a1..6e1ac05ba 100644 --- a/python/quantum-pecos/src/pecos/qeclib/steane/meas/destructive_meas.py +++ b/python/quantum-pecos/src/pecos/slr/qeclib/steane/meas/destructive_meas.py @@ -18,9 +18,9 @@ from typing import TYPE_CHECKING -from pecos.qeclib import qubit -from pecos.qeclib.steane.gates_sq.sqrt_paulis import SX, SYdg from pecos.slr import Barrier, Block, Comment, If +from pecos.slr.qeclib import qubit +from pecos.slr.qeclib.steane.gates_sq.sqrt_paulis import SX, SYdg if TYPE_CHECKING: from pecos.slr import Bit, CReg, QReg diff --git a/python/quantum-pecos/src/pecos/qeclib/steane/meas/measure_x.py b/python/quantum-pecos/src/pecos/slr/qeclib/steane/meas/measure_x.py similarity index 98% rename from python/quantum-pecos/src/pecos/qeclib/steane/meas/measure_x.py rename to python/quantum-pecos/src/pecos/slr/qeclib/steane/meas/measure_x.py index 11c841e42..58e5013b4 100644 --- a/python/quantum-pecos/src/pecos/qeclib/steane/meas/measure_x.py +++ b/python/quantum-pecos/src/pecos/slr/qeclib/steane/meas/measure_x.py @@ -15,8 +15,8 @@ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. -from pecos.qeclib import qubit from pecos.slr import Block, Comment, CReg, QReg, Qubit +from pecos.slr.qeclib import qubit class NoFlagMeasureX(Block): diff --git a/python/quantum-pecos/src/pecos/qeclib/steane/meas/measure_z.py b/python/quantum-pecos/src/pecos/slr/qeclib/steane/meas/measure_z.py similarity index 98% rename from python/quantum-pecos/src/pecos/qeclib/steane/meas/measure_z.py rename to python/quantum-pecos/src/pecos/slr/qeclib/steane/meas/measure_z.py index 87aec7551..95de90d03 100644 --- a/python/quantum-pecos/src/pecos/qeclib/steane/meas/measure_z.py +++ b/python/quantum-pecos/src/pecos/slr/qeclib/steane/meas/measure_z.py @@ -15,8 +15,8 @@ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. -from pecos.qeclib import qubit from pecos.slr import Block, Comment, CReg, QReg, Qubit +from pecos.slr.qeclib import qubit class NoFlagMeasureZ(Block): diff --git a/python/quantum-pecos/src/pecos/qeclib/steane/preps/__init__.py b/python/quantum-pecos/src/pecos/slr/qeclib/steane/preps/__init__.py similarity index 100% rename from python/quantum-pecos/src/pecos/qeclib/steane/preps/__init__.py rename to python/quantum-pecos/src/pecos/slr/qeclib/steane/preps/__init__.py diff --git a/python/quantum-pecos/src/pecos/qeclib/steane/preps/encoding_circ.py b/python/quantum-pecos/src/pecos/slr/qeclib/steane/preps/encoding_circ.py similarity index 98% rename from python/quantum-pecos/src/pecos/qeclib/steane/preps/encoding_circ.py rename to python/quantum-pecos/src/pecos/slr/qeclib/steane/preps/encoding_circ.py index b39d31b28..e7e222212 100644 --- a/python/quantum-pecos/src/pecos/qeclib/steane/preps/encoding_circ.py +++ b/python/quantum-pecos/src/pecos/slr/qeclib/steane/preps/encoding_circ.py @@ -15,9 +15,9 @@ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. -from pecos.qeclib import qubit from pecos.slr import Block, Comment, QReg from pecos.slr.misc import Return +from pecos.slr.qeclib import qubit from pecos.slr.types import Array, QubitType diff --git a/python/quantum-pecos/src/pecos/qeclib/steane/preps/pauli_states.py b/python/quantum-pecos/src/pecos/slr/qeclib/steane/preps/pauli_states.py similarity index 97% rename from python/quantum-pecos/src/pecos/qeclib/steane/preps/pauli_states.py rename to python/quantum-pecos/src/pecos/slr/qeclib/steane/preps/pauli_states.py index 1f38efeb8..af0e34ecf 100644 --- a/python/quantum-pecos/src/pecos/qeclib/steane/preps/pauli_states.py +++ b/python/quantum-pecos/src/pecos/slr/qeclib/steane/preps/pauli_states.py @@ -15,13 +15,13 @@ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. -from pecos.qeclib import qubit -from pecos.qeclib.qubit import Prep -from pecos.qeclib.steane.gates_sq import sqrt_paulis -from pecos.qeclib.steane.gates_sq.hadamards import H -from pecos.qeclib.steane.gates_sq.paulis import X, Z from pecos.slr import Barrier, Bit, Block, Comment, If, QReg, Qubit, Repeat from pecos.slr.misc import Return +from pecos.slr.qeclib import qubit +from pecos.slr.qeclib.qubit import Prep +from pecos.slr.qeclib.steane.gates_sq import sqrt_paulis +from pecos.slr.qeclib.steane.gates_sq.hadamards import H +from pecos.slr.qeclib.steane.gates_sq.paulis import X, Z from pecos.slr.types import Array, QubitType diff --git a/python/quantum-pecos/src/pecos/qeclib/steane/preps/plus_h_state.py b/python/quantum-pecos/src/pecos/slr/qeclib/steane/preps/plus_h_state.py similarity index 96% rename from python/quantum-pecos/src/pecos/qeclib/steane/preps/plus_h_state.py rename to python/quantum-pecos/src/pecos/slr/qeclib/steane/preps/plus_h_state.py index f0914c951..db3b946a4 100644 --- a/python/quantum-pecos/src/pecos/qeclib/steane/preps/plus_h_state.py +++ b/python/quantum-pecos/src/pecos/slr/qeclib/steane/preps/plus_h_state.py @@ -16,15 +16,15 @@ # specific language governing permissions and limitations under the License. import pecos as pc -from pecos.qeclib import qubit -from pecos.qeclib.generic.check_1flag import Check1Flag -from pecos.qeclib.steane.preps.encoding_circ import EncodingCircuit -from pecos.qeclib.steane.syn_extract.three_parallel_flagging import ( +from pecos.slr import Bit, Block, Comment, CReg, If, QReg, Repeat +from pecos.slr.misc import Return +from pecos.slr.qeclib import qubit +from pecos.slr.qeclib.generic.check_1flag import Check1Flag +from pecos.slr.qeclib.steane.preps.encoding_circ import EncodingCircuit +from pecos.slr.qeclib.steane.syn_extract.three_parallel_flagging import ( ThreeParallelFlaggingXZZ, ThreeParallelFlaggingZXX, ) -from pecos.slr import Bit, Block, Comment, CReg, If, QReg, Repeat -from pecos.slr.misc import Return from pecos.slr.types import Array, QubitType diff --git a/python/quantum-pecos/src/pecos/qeclib/steane/preps/t_plus_state.py b/python/quantum-pecos/src/pecos/slr/qeclib/steane/preps/t_plus_state.py similarity index 96% rename from python/quantum-pecos/src/pecos/qeclib/steane/preps/t_plus_state.py rename to python/quantum-pecos/src/pecos/slr/qeclib/steane/preps/t_plus_state.py index 93c7a547f..c6061319c 100644 --- a/python/quantum-pecos/src/pecos/qeclib/steane/preps/t_plus_state.py +++ b/python/quantum-pecos/src/pecos/slr/qeclib/steane/preps/t_plus_state.py @@ -15,12 +15,12 @@ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. -from pecos.qeclib import qubit -from pecos.qeclib.steane.gates_sq.face_rots import F -from pecos.qeclib.steane.preps.encoding_circ import EncodingCircuit -from pecos.qeclib.steane.preps.plus_h_state import PrepHStateFT, PrepHStateFTRUS from pecos.slr import Bit, Block, Comment, CReg, QReg from pecos.slr.misc import Return +from pecos.slr.qeclib import qubit +from pecos.slr.qeclib.steane.gates_sq.face_rots import F +from pecos.slr.qeclib.steane.preps.encoding_circ import EncodingCircuit +from pecos.slr.qeclib.steane.preps.plus_h_state import PrepHStateFT, PrepHStateFTRUS from pecos.slr.types import Array, QubitType diff --git a/python/quantum-pecos/src/pecos/qeclib/steane/qec/__init__.py b/python/quantum-pecos/src/pecos/slr/qeclib/steane/qec/__init__.py similarity index 100% rename from python/quantum-pecos/src/pecos/qeclib/steane/qec/__init__.py rename to python/quantum-pecos/src/pecos/slr/qeclib/steane/qec/__init__.py diff --git a/python/quantum-pecos/src/pecos/qeclib/steane/qec/qec_3parallel.py b/python/quantum-pecos/src/pecos/slr/qeclib/steane/qec/qec_3parallel.py similarity index 96% rename from python/quantum-pecos/src/pecos/qeclib/steane/qec/qec_3parallel.py rename to python/quantum-pecos/src/pecos/slr/qeclib/steane/qec/qec_3parallel.py index 980d4f1f3..d088a4cd3 100644 --- a/python/quantum-pecos/src/pecos/qeclib/steane/qec/qec_3parallel.py +++ b/python/quantum-pecos/src/pecos/slr/qeclib/steane/qec/qec_3parallel.py @@ -15,17 +15,17 @@ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. -from pecos.qeclib.steane.decoders.lookup import ( +from pecos.slr import Bit, Block, CReg, If, QReg +from pecos.slr.qeclib.steane.decoders.lookup import ( FlagLookupQASM, FlagLookupQASMActiveCorrectionX, FlagLookupQASMActiveCorrectionZ, ) -from pecos.qeclib.steane.syn_extract.six_check_nonflagging import SixUnflaggedSyn -from pecos.qeclib.steane.syn_extract.three_parallel_flagging import ( +from pecos.slr.qeclib.steane.syn_extract.six_check_nonflagging import SixUnflaggedSyn +from pecos.slr.qeclib.steane.syn_extract.three_parallel_flagging import ( ThreeParallelFlaggingXZZ, ThreeParallelFlaggingZXX, ) -from pecos.slr import Bit, Block, CReg, If, QReg class ParallelFlagQECActiveCorrection(Block): diff --git a/python/quantum-pecos/src/pecos/qeclib/steane/steane.py b/python/quantum-pecos/src/pecos/slr/qeclib/steane/steane.py similarity index 97% rename from python/quantum-pecos/src/pecos/qeclib/steane/steane.py rename to python/quantum-pecos/src/pecos/slr/qeclib/steane/steane.py index 50cf2b6e9..c79f7bf1d 100644 --- a/python/quantum-pecos/src/pecos/qeclib/steane/steane.py +++ b/python/quantum-pecos/src/pecos/slr/qeclib/steane/steane.py @@ -20,21 +20,22 @@ from typing import TYPE_CHECKING from warnings import warn -# from pecos.qeclib.qubit.qubit import PhysicalQubit +from pecos.slr import Block, CReg, If, Permute, QReg, Vars + +# from pecos.slr.qeclib.qubit.qubit import PhysicalQubit # TODO: Use physical qubit implementation... accept multiple arguments # TODO: Make sure the Steane gate api matches the physical qubit api # TODO: Consider using Protocol to avoid inheritance but ensure unified API -from pecos.qeclib.steane.gates_sq import paulis, sqrt_paulis -from pecos.qeclib.steane.gates_sq.hadamards import H -from pecos.qeclib.steane.gates_tq import transversal_tq -from pecos.qeclib.steane.meas.destructive_meas import MeasDecode -from pecos.qeclib.steane.preps.pauli_states import PrepRUS -from pecos.qeclib.steane.preps.t_plus_state import ( +from pecos.slr.qeclib.steane.gates_sq import paulis, sqrt_paulis +from pecos.slr.qeclib.steane.gates_sq.hadamards import H +from pecos.slr.qeclib.steane.gates_tq import transversal_tq +from pecos.slr.qeclib.steane.meas.destructive_meas import MeasDecode +from pecos.slr.qeclib.steane.preps.pauli_states import PrepRUS +from pecos.slr.qeclib.steane.preps.t_plus_state import ( PrepEncodeTPlusFTRUS, PrepEncodeTPlusNonFT, ) -from pecos.qeclib.steane.qec.qec_3parallel import ParallelFlagQECActiveCorrection -from pecos.slr import Block, CReg, If, Permute, QReg, Vars +from pecos.slr.qeclib.steane.qec.qec_3parallel import ParallelFlagQECActiveCorrection if TYPE_CHECKING: from pecos.slr import Bit diff --git a/python/quantum-pecos/src/pecos/qeclib/steane/steane_class.py b/python/quantum-pecos/src/pecos/slr/qeclib/steane/steane_class.py similarity index 97% rename from python/quantum-pecos/src/pecos/qeclib/steane/steane_class.py rename to python/quantum-pecos/src/pecos/slr/qeclib/steane/steane_class.py index c8bdbbc5e..f758f07a4 100644 --- a/python/quantum-pecos/src/pecos/qeclib/steane/steane_class.py +++ b/python/quantum-pecos/src/pecos/slr/qeclib/steane/steane_class.py @@ -20,26 +20,26 @@ from typing import TYPE_CHECKING, NoReturn from warnings import warn -from pecos.qeclib.steane.decoders.lookup import ( +from pecos.slr import Block, CReg, If, Permute, QReg, Vars +from pecos.slr.qeclib.steane.decoders.lookup import ( FlagLookupQASMActiveCorrectionX, FlagLookupQASMActiveCorrectionZ, ) -from pecos.qeclib.steane.gates_sq import paulis, sqrt_paulis -from pecos.qeclib.steane.gates_sq.hadamards import H -from pecos.qeclib.steane.gates_tq import transversal_tq -from pecos.qeclib.steane.meas.destructive_meas import MeasDecode -from pecos.qeclib.steane.preps.pauli_states import PrepRUS -from pecos.qeclib.steane.preps.t_plus_state import ( +from pecos.slr.qeclib.steane.gates_sq import paulis, sqrt_paulis +from pecos.slr.qeclib.steane.gates_sq.hadamards import H +from pecos.slr.qeclib.steane.gates_tq import transversal_tq +from pecos.slr.qeclib.steane.meas.destructive_meas import MeasDecode +from pecos.slr.qeclib.steane.preps.pauli_states import PrepRUS +from pecos.slr.qeclib.steane.preps.t_plus_state import ( PrepEncodeTPlusFTRUS, PrepEncodeTPlusNonFT, ) -from pecos.qeclib.steane.qec.qec_3parallel import ( +from pecos.slr.qeclib.steane.qec.qec_3parallel import ( ParallelFlagQEC, ParallelFlagQECActiveCorrection, ) -from pecos.qeclib.steane.syn_extract.bare import SynExtractBare -from pecos.qeclib.steane.syn_extract.flagged import SynExtractFlagged -from pecos.slr import Block, CReg, If, Permute, QReg, Vars +from pecos.slr.qeclib.steane.syn_extract.bare import SynExtractBare +from pecos.slr.qeclib.steane.syn_extract.flagged import SynExtractFlagged if TYPE_CHECKING: from pecos.slr import Bit diff --git a/python/quantum-pecos/src/pecos/qeclib/steane/steane_simple_class.py b/python/quantum-pecos/src/pecos/slr/qeclib/steane/steane_simple_class.py similarity index 92% rename from python/quantum-pecos/src/pecos/qeclib/steane/steane_simple_class.py rename to python/quantum-pecos/src/pecos/slr/qeclib/steane/steane_simple_class.py index 6942ed718..bfa34aff5 100644 --- a/python/quantum-pecos/src/pecos/qeclib/steane/steane_simple_class.py +++ b/python/quantum-pecos/src/pecos/slr/qeclib/steane/steane_simple_class.py @@ -19,14 +19,14 @@ from typing import TYPE_CHECKING -from pecos.qeclib.steane.gates_sq import paulis, sqrt_paulis -from pecos.qeclib.steane.gates_sq.hadamards import H -from pecos.qeclib.steane.gates_tq import transversal_tq -from pecos.qeclib.steane.meas.destructive_meas import Measure -from pecos.qeclib.steane.preps.pauli_states import PrepRUS -from pecos.qeclib.steane.syn_extract.bare import SynExtractBare -from pecos.qeclib.steane.syn_extract.flagged import SynExtractFlagged from pecos.slr import CReg, QReg, Vars +from pecos.slr.qeclib.steane.gates_sq import paulis, sqrt_paulis +from pecos.slr.qeclib.steane.gates_sq.hadamards import H +from pecos.slr.qeclib.steane.gates_tq import transversal_tq +from pecos.slr.qeclib.steane.meas.destructive_meas import Measure +from pecos.slr.qeclib.steane.preps.pauli_states import PrepRUS +from pecos.slr.qeclib.steane.syn_extract.bare import SynExtractBare +from pecos.slr.qeclib.steane.syn_extract.flagged import SynExtractFlagged if TYPE_CHECKING: from pecos.slr import Bit, Block diff --git a/python/quantum-pecos/src/pecos/qeclib/steane/syn_extract/__init__.py b/python/quantum-pecos/src/pecos/slr/qeclib/steane/syn_extract/__init__.py similarity index 100% rename from python/quantum-pecos/src/pecos/qeclib/steane/syn_extract/__init__.py rename to python/quantum-pecos/src/pecos/slr/qeclib/steane/syn_extract/__init__.py diff --git a/python/quantum-pecos/src/pecos/qeclib/steane/syn_extract/bare.py b/python/quantum-pecos/src/pecos/slr/qeclib/steane/syn_extract/bare.py similarity index 98% rename from python/quantum-pecos/src/pecos/qeclib/steane/syn_extract/bare.py rename to python/quantum-pecos/src/pecos/slr/qeclib/steane/syn_extract/bare.py index 63c0a3ced..450bde048 100644 --- a/python/quantum-pecos/src/pecos/qeclib/steane/syn_extract/bare.py +++ b/python/quantum-pecos/src/pecos/slr/qeclib/steane/syn_extract/bare.py @@ -7,8 +7,8 @@ from itertools import cycle from typing import Any -from pecos.qeclib.generic.check import Check from pecos.slr import Block, Comment, CReg, QReg +from pecos.slr.qeclib.generic.check import Check def poly2qubits(poly: list[Any], data: QReg) -> list[Any]: diff --git a/python/quantum-pecos/src/pecos/qeclib/steane/syn_extract/flagged.py b/python/quantum-pecos/src/pecos/slr/qeclib/steane/syn_extract/flagged.py similarity index 98% rename from python/quantum-pecos/src/pecos/qeclib/steane/syn_extract/flagged.py rename to python/quantum-pecos/src/pecos/slr/qeclib/steane/syn_extract/flagged.py index ca6d86ce4..579ddd03e 100644 --- a/python/quantum-pecos/src/pecos/qeclib/steane/syn_extract/flagged.py +++ b/python/quantum-pecos/src/pecos/slr/qeclib/steane/syn_extract/flagged.py @@ -8,8 +8,8 @@ from itertools import cycle from typing import Any -from pecos.qeclib.generic.check_1flag import Check1Flag from pecos.slr import Block, Comment, CReg, QReg +from pecos.slr.qeclib.generic.check_1flag import Check1Flag def poly2qubits(poly: list[Any], data: QReg) -> list[Any]: diff --git a/python/quantum-pecos/src/pecos/qeclib/steane/syn_extract/six_check_nonflagging.py b/python/quantum-pecos/src/pecos/slr/qeclib/steane/syn_extract/six_check_nonflagging.py similarity index 99% rename from python/quantum-pecos/src/pecos/qeclib/steane/syn_extract/six_check_nonflagging.py rename to python/quantum-pecos/src/pecos/slr/qeclib/steane/syn_extract/six_check_nonflagging.py index 173a5ba94..3ccc9831f 100644 --- a/python/quantum-pecos/src/pecos/qeclib/steane/syn_extract/six_check_nonflagging.py +++ b/python/quantum-pecos/src/pecos/slr/qeclib/steane/syn_extract/six_check_nonflagging.py @@ -14,8 +14,8 @@ # Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. -from pecos.qeclib import qubit as gq from pecos.slr import Block, Comment, CReg, QReg +from pecos.slr.qeclib import qubit as gq class SixUnflaggedSyn(Block): diff --git a/python/quantum-pecos/src/pecos/qeclib/steane/syn_extract/three_parallel_flagging.py b/python/quantum-pecos/src/pecos/slr/qeclib/steane/syn_extract/three_parallel_flagging.py similarity index 99% rename from python/quantum-pecos/src/pecos/qeclib/steane/syn_extract/three_parallel_flagging.py rename to python/quantum-pecos/src/pecos/slr/qeclib/steane/syn_extract/three_parallel_flagging.py index 0eaaa2f5d..06d99c0f8 100644 --- a/python/quantum-pecos/src/pecos/qeclib/steane/syn_extract/three_parallel_flagging.py +++ b/python/quantum-pecos/src/pecos/slr/qeclib/steane/syn_extract/three_parallel_flagging.py @@ -15,8 +15,8 @@ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. -from pecos.qeclib import qubit as gq from pecos.slr import Barrier, Block, Comment, CReg, QReg +from pecos.slr.qeclib import qubit as gq class ThreeParallelFlaggingXZZ(Block): diff --git a/python/quantum-pecos/src/pecos/qeclib/surface/__init__.py b/python/quantum-pecos/src/pecos/slr/qeclib/surface/__init__.py similarity index 65% rename from python/quantum-pecos/src/pecos/qeclib/surface/__init__.py rename to python/quantum-pecos/src/pecos/slr/qeclib/surface/__init__.py index a919232a6..634e904b0 100644 --- a/python/quantum-pecos/src/pecos/qeclib/surface/__init__.py +++ b/python/quantum-pecos/src/pecos/slr/qeclib/surface/__init__.py @@ -11,15 +11,18 @@ """Surface code quantum error correction library.""" -from pecos.qeclib.surface.gate_sets.surface_std_gates import SurfaceStdGates -from pecos.qeclib.surface.layouts.layout_base import LatticeType -from pecos.qeclib.surface.patch_builders import SurfacePatchBuilder -from pecos.qeclib.surface.patches.patch_base import SurfacePatchOrientation -from pecos.qeclib.surface.patches.surface_patches import ( +from pecos.slr.qeclib.surface.gate_sets.surface_std_gates import SurfaceStdGates +from pecos.slr.qeclib.surface.layouts.layout_base import LatticeType +from pecos.slr.qeclib.surface.patch_builders import SurfacePatchBuilder +from pecos.slr.qeclib.surface.patches.patch_base import SurfacePatchOrientation +from pecos.slr.qeclib.surface.patches.surface_patches import ( NonRotatedSurfacePatch, RotatedSurfacePatch, ) -from pecos.qeclib.surface.visualization.lattice_2d import Lattice2DConfig, Lattice2DView +from pecos.slr.qeclib.surface.visualization.lattice_2d import ( + Lattice2DConfig, + Lattice2DView, +) __all__ = [ "Lattice2DConfig", diff --git a/python/quantum-pecos/src/pecos/qeclib/surface/gate_sets/__init__.py b/python/quantum-pecos/src/pecos/slr/qeclib/surface/gate_sets/__init__.py similarity index 100% rename from python/quantum-pecos/src/pecos/qeclib/surface/gate_sets/__init__.py rename to python/quantum-pecos/src/pecos/slr/qeclib/surface/gate_sets/__init__.py diff --git a/python/quantum-pecos/src/pecos/qeclib/surface/gate_sets/surface_bare_syn_gates.py b/python/quantum-pecos/src/pecos/slr/qeclib/surface/gate_sets/surface_bare_syn_gates.py similarity index 89% rename from python/quantum-pecos/src/pecos/qeclib/surface/gate_sets/surface_bare_syn_gates.py rename to python/quantum-pecos/src/pecos/slr/qeclib/surface/gate_sets/surface_bare_syn_gates.py index c4bf7c325..4805f6309 100644 --- a/python/quantum-pecos/src/pecos/qeclib/surface/gate_sets/surface_bare_syn_gates.py +++ b/python/quantum-pecos/src/pecos/slr/qeclib/surface/gate_sets/surface_bare_syn_gates.py @@ -1,6 +1,6 @@ """Bare syndrome extraction gates for surface codes.""" -from pecos.qeclib.surface.patches.patch_base import SurfacePatch +from pecos.slr.qeclib.surface.patches.patch_base import SurfacePatch class SurfaceBareSynGates: diff --git a/python/quantum-pecos/src/pecos/qeclib/surface/gate_sets/surface_meas_prep_gates.py b/python/quantum-pecos/src/pecos/slr/qeclib/surface/gate_sets/surface_meas_prep_gates.py similarity index 83% rename from python/quantum-pecos/src/pecos/qeclib/surface/gate_sets/surface_meas_prep_gates.py rename to python/quantum-pecos/src/pecos/slr/qeclib/surface/gate_sets/surface_meas_prep_gates.py index 032502d99..3d6939b8e 100644 --- a/python/quantum-pecos/src/pecos/qeclib/surface/gate_sets/surface_meas_prep_gates.py +++ b/python/quantum-pecos/src/pecos/slr/qeclib/surface/gate_sets/surface_meas_prep_gates.py @@ -1,8 +1,8 @@ """Measurement and preparation gates for surface codes.""" -from pecos.qeclib.surface.macrolibs.preps.project_pauli import PrepProjectZ -from pecos.qeclib.surface.patches.patch_base import SurfacePatch from pecos.slr import Bit +from pecos.slr.qeclib.surface.macrolibs.preps.project_pauli import PrepProjectZ +from pecos.slr.qeclib.surface.patches.patch_base import SurfacePatch class SurfaceMeasPrepGates: diff --git a/python/quantum-pecos/src/pecos/qeclib/surface/gate_sets/surface_std_gates.py b/python/quantum-pecos/src/pecos/slr/qeclib/surface/gate_sets/surface_std_gates.py similarity index 58% rename from python/quantum-pecos/src/pecos/qeclib/surface/gate_sets/surface_std_gates.py rename to python/quantum-pecos/src/pecos/slr/qeclib/surface/gate_sets/surface_std_gates.py index e583f1c58..17adf079c 100644 --- a/python/quantum-pecos/src/pecos/qeclib/surface/gate_sets/surface_std_gates.py +++ b/python/quantum-pecos/src/pecos/slr/qeclib/surface/gate_sets/surface_std_gates.py @@ -1,12 +1,12 @@ """Standard gate sets for surface codes.""" -from pecos.qeclib.surface.gate_sets.surface_bare_syn_gates import ( +from pecos.slr.qeclib.surface.gate_sets.surface_bare_syn_gates import ( SurfaceBareSynGates, ) -from pecos.qeclib.surface.gate_sets.surface_meas_prep_gates import ( +from pecos.slr.qeclib.surface.gate_sets.surface_meas_prep_gates import ( SurfaceMeasPrepGates, ) -from pecos.qeclib.surface.gate_sets.surface_transversal_gates import ( +from pecos.slr.qeclib.surface.gate_sets.surface_transversal_gates import ( SurfaceTransversalGates, ) diff --git a/python/quantum-pecos/src/pecos/qeclib/surface/gate_sets/surface_transversal_gates.py b/python/quantum-pecos/src/pecos/slr/qeclib/surface/gate_sets/surface_transversal_gates.py similarity index 91% rename from python/quantum-pecos/src/pecos/qeclib/surface/gate_sets/surface_transversal_gates.py rename to python/quantum-pecos/src/pecos/slr/qeclib/surface/gate_sets/surface_transversal_gates.py index 1eec7bad8..37b0cd7a2 100644 --- a/python/quantum-pecos/src/pecos/qeclib/surface/gate_sets/surface_transversal_gates.py +++ b/python/quantum-pecos/src/pecos/slr/qeclib/surface/gate_sets/surface_transversal_gates.py @@ -5,7 +5,7 @@ from typing import TYPE_CHECKING if TYPE_CHECKING: - from pecos.qeclib.surface.patches.patch_base import SurfacePatch + from pecos.slr.qeclib.surface.patches.patch_base import SurfacePatch class SurfaceTransversalGates: @@ -37,7 +37,7 @@ def h(*patches: SurfacePatch, permute: bool = True) -> None: Examples: ```python from pecos.slr import Main - from pecos.qeclib.surface import Surface4444RotPatch as SP + from pecos.slr.qeclib.surface import Surface4444RotPatch as SP prog = Main( s := [SP.new(3) for _ in range(4)], @@ -62,7 +62,7 @@ def cx( Examples: ```python from pecos.slr import Main - from pecos.qeclib.surface import Surface4444RotPatch as SP + from pecos.slr.qeclib.surface import Surface4444RotPatch as SP prog = Main( s := [SP.new(3) for _ in range(4)], diff --git a/python/quantum-pecos/src/pecos/qeclib/surface/layouts/__init__.py b/python/quantum-pecos/src/pecos/slr/qeclib/surface/layouts/__init__.py similarity index 100% rename from python/quantum-pecos/src/pecos/qeclib/surface/layouts/__init__.py rename to python/quantum-pecos/src/pecos/slr/qeclib/surface/layouts/__init__.py diff --git a/python/quantum-pecos/src/pecos/qeclib/surface/layouts/layout_base.py b/python/quantum-pecos/src/pecos/slr/qeclib/surface/layouts/layout_base.py similarity index 93% rename from python/quantum-pecos/src/pecos/qeclib/surface/layouts/layout_base.py rename to python/quantum-pecos/src/pecos/slr/qeclib/surface/layouts/layout_base.py index 3ca75ded8..df41e298c 100644 --- a/python/quantum-pecos/src/pecos/qeclib/surface/layouts/layout_base.py +++ b/python/quantum-pecos/src/pecos/slr/qeclib/surface/layouts/layout_base.py @@ -3,7 +3,7 @@ from enum import Enum from typing import Protocol -from pecos.qeclib.surface.visualization.visualization_base import VisualizationData +from pecos.slr.qeclib.surface.visualization.visualization_base import VisualizationData class LatticeType(Enum): diff --git a/python/quantum-pecos/src/pecos/qeclib/surface/layouts/rot_square_lattice.py b/python/quantum-pecos/src/pecos/slr/qeclib/surface/layouts/rot_square_lattice.py similarity index 99% rename from python/quantum-pecos/src/pecos/qeclib/surface/layouts/rot_square_lattice.py rename to python/quantum-pecos/src/pecos/slr/qeclib/surface/layouts/rot_square_lattice.py index c2ee6940a..a0ede0183 100644 --- a/python/quantum-pecos/src/pecos/qeclib/surface/layouts/rot_square_lattice.py +++ b/python/quantum-pecos/src/pecos/slr/qeclib/surface/layouts/rot_square_lattice.py @@ -18,7 +18,7 @@ """ -from pecos.qeclib.surface.visualization.visualization_base import VisualizationData +from pecos.slr.qeclib.surface.visualization.visualization_base import VisualizationData class SquareRotatedLayout: diff --git a/python/quantum-pecos/src/pecos/slr/qeclib/surface/layouts/square_lattice.py b/python/quantum-pecos/src/pecos/slr/qeclib/surface/layouts/square_lattice.py new file mode 100644 index 000000000..ae7ae1234 --- /dev/null +++ b/python/quantum-pecos/src/pecos/slr/qeclib/surface/layouts/square_lattice.py @@ -0,0 +1,40 @@ +# Copyright 2018 The PECOS Developers +# Copyright 2018 National Technology & Engineering Solutions of Sandia, LLC (NTESS). Under the terms of Contract +# DE-NA0003525 with NTESS, the U.S. Government retains certain rights in this software. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with +# the License.You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. + +"""Square lattice layout generation for surface codes. + +This module re-exports the layout function from pecos.qec.surface.layouts. +""" + +from pecos.qec.surface.layouts import generate_nonrotated_surface_layout + + +def gen_layout( + width: int, + height: int, +) -> tuple[list[tuple[int, int]], list[tuple[int, int]], list[list[tuple[int, int]]]]: + """Generate rectangular surface code patch layout for a 4.4.4.4 lattice. + + This generates the non-rotated surface code layout. + + Args: + width: Width of the patch in logical qubits. + height: Height of the patch in logical qubits. + + Returns: + A tuple containing: + - nodes: List of (x, y) coordinates for data qubits. + - dual_nodes: List of (x, y) coordinates for ancilla qubits. + - polygons: List of polygons representing stabilizer checks. + """ + return generate_nonrotated_surface_layout(width, height) diff --git a/python/quantum-pecos/src/pecos/qeclib/surface/macrolibs/__init__.py b/python/quantum-pecos/src/pecos/slr/qeclib/surface/macrolibs/__init__.py similarity index 100% rename from python/quantum-pecos/src/pecos/qeclib/surface/macrolibs/__init__.py rename to python/quantum-pecos/src/pecos/slr/qeclib/surface/macrolibs/__init__.py diff --git a/python/quantum-pecos/src/pecos/qeclib/surface/macrolibs/preps/__init__.py b/python/quantum-pecos/src/pecos/slr/qeclib/surface/macrolibs/preps/__init__.py similarity index 100% rename from python/quantum-pecos/src/pecos/qeclib/surface/macrolibs/preps/__init__.py rename to python/quantum-pecos/src/pecos/slr/qeclib/surface/macrolibs/preps/__init__.py diff --git a/python/quantum-pecos/src/pecos/qeclib/surface/macrolibs/preps/project_pauli.py b/python/quantum-pecos/src/pecos/slr/qeclib/surface/macrolibs/preps/project_pauli.py similarity index 96% rename from python/quantum-pecos/src/pecos/qeclib/surface/macrolibs/preps/project_pauli.py rename to python/quantum-pecos/src/pecos/slr/qeclib/surface/macrolibs/preps/project_pauli.py index 6f121b988..debe63dca 100644 --- a/python/quantum-pecos/src/pecos/qeclib/surface/macrolibs/preps/project_pauli.py +++ b/python/quantum-pecos/src/pecos/slr/qeclib/surface/macrolibs/preps/project_pauli.py @@ -11,8 +11,8 @@ """Pauli projection preparation blocks for surface code operations.""" -from pecos.qeclib.qubit.qubit import PhysicalQubit as Q from pecos.slr import Block, QReg, Qubit +from pecos.slr.qeclib.qubit.qubit import PhysicalQubit as Q class PrepZ(Block): diff --git a/python/quantum-pecos/src/pecos/qeclib/surface/macrolibs/syn_extract/__init__.py b/python/quantum-pecos/src/pecos/slr/qeclib/surface/macrolibs/syn_extract/__init__.py similarity index 100% rename from python/quantum-pecos/src/pecos/qeclib/surface/macrolibs/syn_extract/__init__.py rename to python/quantum-pecos/src/pecos/slr/qeclib/surface/macrolibs/syn_extract/__init__.py diff --git a/python/quantum-pecos/src/pecos/qeclib/surface/patch_builders.py b/python/quantum-pecos/src/pecos/slr/qeclib/surface/patch_builders.py similarity index 91% rename from python/quantum-pecos/src/pecos/qeclib/surface/patch_builders.py rename to python/quantum-pecos/src/pecos/slr/qeclib/surface/patch_builders.py index 537e045be..6df0f4f62 100644 --- a/python/quantum-pecos/src/pecos/qeclib/surface/patch_builders.py +++ b/python/quantum-pecos/src/pecos/slr/qeclib/surface/patch_builders.py @@ -3,15 +3,15 @@ from typing import TYPE_CHECKING, TypeVar from pecos.exceptions import ConfigurationError -from pecos.qeclib.surface.layouts.layout_base import LatticeType -from pecos.qeclib.surface.patches.patch_base import SurfacePatchOrientation -from pecos.qeclib.surface.patches.surface_patches import ( +from pecos.slr.qeclib.surface.layouts.layout_base import LatticeType +from pecos.slr.qeclib.surface.patches.patch_base import SurfacePatchOrientation +from pecos.slr.qeclib.surface.patches.surface_patches import ( NonRotatedSurfacePatch, RotatedSurfacePatch, ) if TYPE_CHECKING: - from pecos.qeclib.surface.patches.patch_base import SurfacePatch + from pecos.slr.qeclib.surface.patches.patch_base import SurfacePatch Self = TypeVar("Self") diff --git a/python/quantum-pecos/src/pecos/qeclib/surface/patches/__init__.py b/python/quantum-pecos/src/pecos/slr/qeclib/surface/patches/__init__.py similarity index 100% rename from python/quantum-pecos/src/pecos/qeclib/surface/patches/__init__.py rename to python/quantum-pecos/src/pecos/slr/qeclib/surface/patches/__init__.py diff --git a/python/quantum-pecos/src/pecos/qeclib/surface/patches/patch_base.py b/python/quantum-pecos/src/pecos/slr/qeclib/surface/patches/patch_base.py similarity index 96% rename from python/quantum-pecos/src/pecos/qeclib/surface/patches/patch_base.py rename to python/quantum-pecos/src/pecos/slr/qeclib/surface/patches/patch_base.py index 66f128269..b50fb6a2f 100644 --- a/python/quantum-pecos/src/pecos/qeclib/surface/patches/patch_base.py +++ b/python/quantum-pecos/src/pecos/slr/qeclib/surface/patches/patch_base.py @@ -5,18 +5,18 @@ from enum import Enum from typing import TYPE_CHECKING, Protocol -from pecos.qeclib.surface.visualization.rotated_lattice import ( +from pecos.slr import QReg, Vars +from pecos.slr.qeclib.surface.visualization.rotated_lattice import ( RotatedLatticeVisualization, ) -from pecos.slr import QReg, Vars if TYPE_CHECKING: - from pecos.qeclib.surface.layouts.layout_base import Layout - from pecos.qeclib.surface.visualization.visualization_base import ( + from pecos.slr import Qubit + from pecos.slr.qeclib.surface.layouts.layout_base import Layout + from pecos.slr.qeclib.surface.visualization.visualization_base import ( VisualizationData, VisualizationStrategy, ) - from pecos.slr import Qubit # TODO: Create a vector or an array of objects... # TODO: Set check scheduling for syn_extract diff --git a/python/quantum-pecos/src/pecos/qeclib/surface/patches/surface_patches.py b/python/quantum-pecos/src/pecos/slr/qeclib/surface/patches/surface_patches.py similarity index 82% rename from python/quantum-pecos/src/pecos/qeclib/surface/patches/surface_patches.py rename to python/quantum-pecos/src/pecos/slr/qeclib/surface/patches/surface_patches.py index cd75eefe4..491248fbf 100644 --- a/python/quantum-pecos/src/pecos/qeclib/surface/patches/surface_patches.py +++ b/python/quantum-pecos/src/pecos/slr/qeclib/surface/patches/surface_patches.py @@ -4,12 +4,12 @@ from typing import TYPE_CHECKING -from pecos.qeclib.surface.layouts.rot_square_lattice import SquareRotatedLayout -from pecos.qeclib.surface.patches.patch_base import BaseSurfacePatch +from pecos.slr.qeclib.surface.layouts.rot_square_lattice import SquareRotatedLayout +from pecos.slr.qeclib.surface.patches.patch_base import BaseSurfacePatch if TYPE_CHECKING: - from pecos.qeclib.surface.layouts.layout_base import Layout - from pecos.qeclib.surface.patches.patch_base import SurfacePatchOrientation + from pecos.slr.qeclib.surface.layouts.layout_base import Layout + from pecos.slr.qeclib.surface.patches.patch_base import SurfacePatchOrientation class RotatedSurfacePatch(BaseSurfacePatch): diff --git a/python/quantum-pecos/src/pecos/qeclib/surface/visualization/__init__.py b/python/quantum-pecos/src/pecos/slr/qeclib/surface/visualization/__init__.py similarity index 100% rename from python/quantum-pecos/src/pecos/qeclib/surface/visualization/__init__.py rename to python/quantum-pecos/src/pecos/slr/qeclib/surface/visualization/__init__.py diff --git a/python/quantum-pecos/src/pecos/qeclib/surface/visualization/lattice_2d.py b/python/quantum-pecos/src/pecos/slr/qeclib/surface/visualization/lattice_2d.py similarity index 97% rename from python/quantum-pecos/src/pecos/qeclib/surface/visualization/lattice_2d.py rename to python/quantum-pecos/src/pecos/slr/qeclib/surface/visualization/lattice_2d.py index 45535508b..052869f41 100644 --- a/python/quantum-pecos/src/pecos/qeclib/surface/visualization/lattice_2d.py +++ b/python/quantum-pecos/src/pecos/slr/qeclib/surface/visualization/lattice_2d.py @@ -11,7 +11,7 @@ from matplotlib import pyplot as plt from matplotlib.path import Path - from pecos.qeclib.surface.patches.patch_base import SurfacePatch + from pecos.slr.qeclib.surface.patches.patch_base import SurfacePatch @dataclass @@ -75,8 +75,8 @@ def plot_colored_polygons( polygon_colors (dict[int, int]): List of indices into `colors` for each polygon. config (Lattice2DConfig | None): Optional Lattice2DConfig object. """ - import matplotlib.pyplot as plt - from matplotlib.patches import Circle, PathPatch + import matplotlib.pyplot as plt # noqa: PLC0415 + from matplotlib.patches import Circle, PathPatch # noqa: PLC0415 c = config @@ -211,7 +211,7 @@ def create_cup_path( Returns: Path: A matplotlib path representing the cup shape. """ - from matplotlib.path import Path + from matplotlib.path import Path # noqa: PLC0415 # Calculate midpoint of the base mid_base = ((base1[0] + base2[0]) / 2, (base1[1] + base2[1]) / 2) diff --git a/python/quantum-pecos/src/pecos/qeclib/surface/visualization/rotated_lattice.py b/python/quantum-pecos/src/pecos/slr/qeclib/surface/visualization/rotated_lattice.py similarity index 81% rename from python/quantum-pecos/src/pecos/qeclib/surface/visualization/rotated_lattice.py rename to python/quantum-pecos/src/pecos/slr/qeclib/surface/visualization/rotated_lattice.py index 1163fec35..9e0677123 100644 --- a/python/quantum-pecos/src/pecos/qeclib/surface/visualization/rotated_lattice.py +++ b/python/quantum-pecos/src/pecos/slr/qeclib/surface/visualization/rotated_lattice.py @@ -3,8 +3,8 @@ from typing import TYPE_CHECKING if TYPE_CHECKING: - from pecos.qeclib.surface.patches.patch_base import SurfacePatch - from pecos.qeclib.surface.visualization.visualization_base import VisData + from pecos.slr.qeclib.surface.patches.patch_base import SurfacePatch + from pecos.slr.qeclib.surface.visualization.visualization_base import VisData class RotatedLatticeVisualization: diff --git a/python/quantum-pecos/src/pecos/qeclib/surface/visualization/visualization_base.py b/python/quantum-pecos/src/pecos/slr/qeclib/surface/visualization/visualization_base.py similarity index 91% rename from python/quantum-pecos/src/pecos/qeclib/surface/visualization/visualization_base.py rename to python/quantum-pecos/src/pecos/slr/qeclib/surface/visualization/visualization_base.py index 08119e270..44cd68d9c 100644 --- a/python/quantum-pecos/src/pecos/qeclib/surface/visualization/visualization_base.py +++ b/python/quantum-pecos/src/pecos/slr/qeclib/surface/visualization/visualization_base.py @@ -5,7 +5,7 @@ from typing import TYPE_CHECKING, NamedTuple, Protocol if TYPE_CHECKING: - from pecos.qeclib.surface.patches.patch_base import SurfacePatch + from pecos.slr.qeclib.surface.patches.patch_base import SurfacePatch class VisualizationData(NamedTuple): diff --git a/python/quantum-pecos/src/pecos/testing.py b/python/quantum-pecos/src/pecos/testing.py index 904562918..b0d8f7417 100644 --- a/python/quantum-pecos/src/pecos/testing.py +++ b/python/quantum-pecos/src/pecos/testing.py @@ -107,22 +107,22 @@ def assert_allclose( if mismatches: # Count total mismatches - n_total_mismatches = sum( + num_total_mismatches = sum( 1 for d, ad in zip(diff_list, abs_desired_list, strict=False) if d > atol + rtol * ad ) msg_parts.append( - f"Mismatched elements: {n_total_mismatches} / {len(actual)}", + f"Mismatched elements: {num_total_mismatches} / {len(actual)}", ) msg_parts.append("Examples of mismatched values:") for idx, act_val, des_val, diff_val in mismatches: msg_parts.append( f" Index {idx}: actual={act_val}, desired={des_val}, diff={diff_val}", ) - if n_total_mismatches > len(mismatches): + if num_total_mismatches > len(mismatches): msg_parts.append( - f" ... and {n_total_mismatches - len(mismatches)} more mismatches", + f" ... and {num_total_mismatches - len(mismatches)} more mismatches", ) raise AssertionError("\n".join(msg_parts)) @@ -205,16 +205,16 @@ def assert_array_less( if verbose and violations: # Show some examples - n_show = min(5, len(violations)) + num_show = min(5, len(violations)) msg_parts.append("Examples of violations:") - for i in range(n_show): + for i in range(num_show): idx, xv, yv = violations[i] msg_parts.append(f" Index {idx}: x={xv}, y={yv}") - if len(violations) > n_show: + if len(violations) > num_show: msg_parts.append( - f" ... and {len(violations) - n_show} more violations", + f" ... and {len(violations) - num_show} more violations", ) raise AssertionError("\n".join(msg_parts)) diff --git a/python/quantum-pecos/tests/pecos/qec/__init__.py b/python/quantum-pecos/tests/pecos/qec/__init__.py new file mode 100644 index 000000000..e1835cabe --- /dev/null +++ b/python/quantum-pecos/tests/pecos/qec/__init__.py @@ -0,0 +1,4 @@ +# Copyright 2024 The PECOS Developers +# Licensed under the Apache License, Version 2.0 + +"""Tests for pecos.qec module.""" diff --git a/python/quantum-pecos/tests/pecos/qec/test_analysis.py b/python/quantum-pecos/tests/pecos/qec/test_analysis.py new file mode 100644 index 000000000..975d359b1 --- /dev/null +++ b/python/quantum-pecos/tests/pecos/qec/test_analysis.py @@ -0,0 +1,219 @@ +# Copyright 2024 The PECOS Developers +# Licensed under the Apache License, Version 2.0 + +"""Tests for pecos.qec.analysis utilities.""" + +import pytest +from pecos.qec.analysis import ( + logical_error_rate, + logical_fidelity, + logical_from_data, + logical_x_from_data, + logical_z_from_data, + lower_bound_fidelity, + syndrome_difference, + syndrome_to_detection_events, +) + + +class TestLogicalExtraction: + """Tests for logical operator extraction from measurement data.""" + + def test_logical_x_all_zeros(self) -> None: + """All-zero data should give logical X = 0.""" + data = [0] * 9 # d=3 + assert logical_x_from_data(3, data) == 0 + + def test_logical_z_all_zeros(self) -> None: + """All-zero data should give logical Z = 0.""" + data = [0] * 9 # d=3 + assert logical_z_from_data(3, data) == 0 + + def test_logical_x_left_column_ones(self) -> None: + """Ones in left column should give logical X = 1.""" + # Left column indices for d=3: 0, 3, 6 + data = [1, 0, 0, 1, 0, 0, 1, 0, 0] + assert logical_x_from_data(3, data) == 1 + + def test_logical_z_top_row_ones(self) -> None: + """Ones in top row should give logical Z = 1.""" + # Top row indices for d=3: 0, 1, 2 + data = [1, 1, 1, 0, 0, 0, 0, 0, 0] + assert logical_z_from_data(3, data) == 1 + + def test_logical_x_even_parity(self) -> None: + """Even number of ones in left column gives 0.""" + data = [1, 0, 0, 1, 0, 0, 0, 0, 0] # 2 ones in left column + assert logical_x_from_data(3, data) == 0 + + def test_logical_z_even_parity(self) -> None: + """Even number of ones in top row gives 0.""" + data = [1, 1, 0, 0, 0, 0, 0, 0, 0] # 2 ones in top row + assert logical_z_from_data(3, data) == 0 + + def test_logical_from_data_both(self) -> None: + """Test combined extraction.""" + data = [1, 1, 1, 1, 0, 0, 1, 0, 0] + x, z = logical_from_data(3, data) + assert x == 1 # 3 ones in left column (0, 3, 6) + assert z == 1 # 3 ones in top row (0, 1, 2) + + def test_logical_x_d5(self) -> None: + """Test logical X for d=5.""" + # Left column indices: 0, 5, 10, 15, 20 + data = [0] * 25 + data[0] = 1 + data[5] = 1 + data[10] = 1 + assert logical_x_from_data(5, data) == 1 + + def test_logical_z_d5(self) -> None: + """Test logical Z for d=5.""" + # Top row indices: 0, 1, 2, 3, 4 + data = [0] * 25 + data[0] = 1 + data[1] = 1 + data[2] = 1 + data[3] = 1 + data[4] = 1 + assert logical_z_from_data(5, data) == 1 + + def test_invalid_data_length(self) -> None: + """Wrong data length should raise ValueError.""" + with pytest.raises(ValueError, match="Expected 9"): + logical_x_from_data(3, [0] * 10) + + +class TestLogicalFidelity: + """Tests for fidelity calculation.""" + + def test_perfect_fidelity(self) -> None: + """All correct outcomes should give fidelity 1.0.""" + outcomes = [[0] * 9 for _ in range(100)] + fid, err = logical_fidelity(outcomes, d=3, basis=0, expected=0) + assert fid == 1.0 + assert err == 0.0 + + def test_zero_fidelity(self) -> None: + """All wrong outcomes should give fidelity 0.0.""" + # All ones in left column for X basis + outcomes = [[1, 0, 0, 1, 0, 0, 1, 0, 0] for _ in range(100)] + fid, err = logical_fidelity(outcomes, d=3, basis=0, expected=0) + assert fid == 0.0 + assert err == 0.0 + + def test_half_fidelity(self) -> None: + """Half correct outcomes should give fidelity 0.5.""" + correct = [0] * 9 + wrong = [1, 0, 0, 1, 0, 0, 1, 0, 0] # logical X = 1 + outcomes = [correct] * 50 + [wrong] * 50 + fid, err = logical_fidelity(outcomes, d=3, basis=0, expected=0) + assert fid == 0.5 + assert err == pytest.approx(0.05, abs=0.01) + + def test_z_basis(self) -> None: + """Test Z basis measurement.""" + correct = [0] * 9 + wrong = [1, 1, 1, 0, 0, 0, 0, 0, 0] # logical Z = 1 + outcomes = [correct] * 80 + [wrong] * 20 + fid, err = logical_fidelity(outcomes, d=3, basis=1, expected=0) + assert fid == 0.8 + assert err == pytest.approx(0.04, abs=0.01) + + def test_empty_outcomes(self) -> None: + """Empty outcomes should raise ValueError.""" + with pytest.raises(ValueError, match="No outcomes"): + logical_fidelity([], d=3, basis=0) + + +class TestLogicalErrorRate: + """Tests for error rate calculation.""" + + def test_error_rate_is_one_minus_fidelity(self) -> None: + """Error rate should be 1 - fidelity.""" + correct = [0] * 9 + wrong = [1, 0, 0, 1, 0, 0, 1, 0, 0] + outcomes = [correct] * 80 + [wrong] * 20 + err_rate, _err_bar = logical_error_rate(outcomes, d=3, basis=0) + fid, _ = logical_fidelity(outcomes, d=3, basis=0) + assert err_rate == pytest.approx(1 - fid) + + +class TestSyndromeDifference: + """Tests for syndrome difference computation.""" + + def test_empty_syndromes(self) -> None: + """Empty input should return empty output.""" + assert syndrome_difference([]) == [] + + def test_single_round(self) -> None: + """Single round should return the syndrome itself.""" + syn = [1, 0, 1, 0] + result = syndrome_difference([syn]) + assert result == [[1, 0, 1, 0]] + + def test_two_identical_rounds(self) -> None: + """Identical rounds should give zero difference.""" + syn = [1, 0, 1, 0] + result = syndrome_difference([syn, syn]) + assert result[0] == [1, 0, 1, 0] # First round vs zeros + assert result[1] == [0, 0, 0, 0] # Second round vs first + + def test_alternating_syndromes(self) -> None: + """Alternating syndromes should show changes.""" + syn1 = [1, 0, 1, 0] + syn2 = [0, 1, 0, 1] + result = syndrome_difference([syn1, syn2]) + assert result[0] == [1, 0, 1, 0] # syn1 XOR 0 + assert result[1] == [1, 1, 1, 1] # syn2 XOR syn1 + + def test_three_rounds(self) -> None: + """Test three-round case.""" + syns = [[1, 1], [1, 0], [0, 0]] + result = syndrome_difference(syns) + assert result[0] == [1, 1] # Round 0 vs zeros + assert result[1] == [0, 1] # Round 1 vs round 0 + assert result[2] == [1, 0] # Round 2 vs round 1 + + +class TestSyndromeToDetectionEvents: + """Tests for detection event extraction.""" + + def test_no_events(self) -> None: + """All-zero syndromes should give no events.""" + syns = [[0, 0], [0, 0], [0, 0]] + events = syndrome_to_detection_events(syns) + assert events == [] + + def test_first_round_events(self) -> None: + """Events in first round (difference from zero).""" + syns = [[1, 0, 1, 0]] + events = syndrome_to_detection_events(syns) + assert (0, 0) in events + assert (2, 0) in events + assert len(events) == 2 + + def test_later_round_events(self) -> None: + """Events from syndrome changes.""" + syns = [[0, 0], [1, 0], [1, 0]] + events = syndrome_to_detection_events(syns) + # Round 0: no events (all zeros) + # Round 1: stabilizer 0 changed + # Round 2: no change from round 1 + assert events == [(0, 1)] + + +class TestLowerBoundFidelity: + """Tests for fidelity lower bound.""" + + def test_perfect_fidelities(self) -> None: + """Perfect fidelities should give bound of 1.0.""" + bound = lower_bound_fidelity(1.0, 1.0) + assert bound == pytest.approx(1.0) + + def test_formula(self) -> None: + """Check the formula is applied correctly.""" + # bound = (4/5) * (f1 + f2) - (3/5) + bound = lower_bound_fidelity(0.9, 0.8) + expected = (4 / 5) * (0.9 + 0.8) - (3 / 5) + assert bound == pytest.approx(expected) diff --git a/python/quantum-pecos/tests/pecos/qec/test_color_geometry.py b/python/quantum-pecos/tests/pecos/qec/test_color_geometry.py new file mode 100644 index 000000000..68f835310 --- /dev/null +++ b/python/quantum-pecos/tests/pecos/qec/test_color_geometry.py @@ -0,0 +1,149 @@ +# Copyright 2024 The PECOS Developers +# Licensed under the Apache License, Version 2.0 + +"""Tests for pecos.qec.color geometry functions.""" + +from dataclasses import FrozenInstanceError + +import pytest +from pecos.qec.color import ( + ColorCode488, + ColorCode488Builder, + ColorCode488Geometry, + ColorCodeStabilizer, + generate_488_layout, +) + + +class TestGenerate488Layout: + """Tests for 4.8.8 color code layout generation.""" + + def test_d3_qubit_count(self) -> None: + """Distance-3 color code should have 7 data qubits.""" + nodeid2pos, _polygons = generate_488_layout(3) + assert len(nodeid2pos) == 7 + + def test_d5_qubit_count(self) -> None: + """Distance-5 color code should have 17 data qubits.""" + nodeid2pos, _polygons = generate_488_layout(5) + assert len(nodeid2pos) == 17 + + def test_d7_qubit_count(self) -> None: + """Distance-7 color code should have 31 data qubits.""" + nodeid2pos, _polygons = generate_488_layout(7) + assert len(nodeid2pos) == 31 + + def test_d3_polygon_count(self) -> None: + """Distance-3 color code should have 3 polygons (stabilizers).""" + _nodeid2pos, polygons = generate_488_layout(3) + assert len(polygons) == 3 + + def test_invalid_distance_even(self) -> None: + """Even distances should raise ValueError.""" + with pytest.raises(ValueError, match="odd"): + generate_488_layout(4) + + def test_invalid_distance_too_small(self) -> None: + """Distance < 3 should raise ValueError.""" + with pytest.raises(ValueError, match="odd"): + generate_488_layout(1) + + def test_positions_are_unique(self) -> None: + """All qubit positions should be unique.""" + nodeid2pos, _ = generate_488_layout(5) + positions = list(nodeid2pos.values()) + assert len(positions) == len(set(positions)) + + def test_polygon_contains_color(self) -> None: + """Each polygon should end with a color string.""" + _, polygons = generate_488_layout(5) + for poly in polygons: + color = poly[-1] + assert color in ("red", "green", "blue") + + +class TestColorCode488: + """Tests for ColorCode488 class.""" + + def test_create_d3(self) -> None: + """Create distance-3 color code.""" + code = ColorCode488.create(distance=3) + assert code.distance == 3 + assert code.num_data == 7 + + def test_create_d5(self) -> None: + """Create distance-5 color code.""" + code = ColorCode488.create(distance=5) + assert code.distance == 5 + assert code.num_data == 17 + + def test_num_stabilizers(self) -> None: + """Check stabilizer count.""" + code = ColorCode488.create(distance=3) + assert code.num_stabilizers == 3 + + def test_stabilizers_have_colors(self) -> None: + """Each stabilizer should have a color.""" + code = ColorCode488.create(distance=5) + for stab in code.stabilizers: + assert stab.color in ("red", "green", "blue") + + def test_get_stabilizers_by_color(self) -> None: + """Filter stabilizers by color.""" + code = ColorCode488.create(distance=5) + red = code.get_stabilizers_by_color("red") + green = code.get_stabilizers_by_color("green") + blue = code.get_stabilizers_by_color("blue") + assert len(red) + len(green) + len(blue) == code.num_stabilizers + + def test_logical_x(self) -> None: + """Logical X should be on bottom boundary.""" + code = ColorCode488.create(distance=3) + logical_x = code.get_logical_x() + assert len(logical_x) == 3 # d qubits for logical operator + + def test_logical_z(self) -> None: + """Logical Z should be on same support (self-dual code).""" + code = ColorCode488.create(distance=3) + logical_z = code.get_logical_z() + assert logical_z == code.get_logical_x() # Self-dual + + def test_parity_matrix_shape(self) -> None: + """Parity matrix should have shape (num_stab, num_data).""" + code = ColorCode488.create(distance=3) + parity_matrix = code.get_parity_matrix() + assert parity_matrix.shape == (code.num_stabilizers, code.num_data) + + +class TestColorCode488Builder: + """Tests for ColorCode488Builder.""" + + def test_builder_pattern(self) -> None: + """Builder should create valid code.""" + code = ColorCode488Builder().with_distance(5).build() + assert code.distance == 5 + + def test_builder_requires_distance(self) -> None: + """Builder should raise if distance not set.""" + with pytest.raises(ValueError, match="Distance"): + ColorCode488Builder().build() + + +class TestColorCodeStabilizer: + """Tests for ColorCodeStabilizer dataclass.""" + + def test_stabilizer_is_frozen(self) -> None: + """ColorCodeStabilizer should be immutable.""" + stab = ColorCodeStabilizer(index=0, qubits=(0, 1, 2), color="red") + with pytest.raises(FrozenInstanceError): + stab.index = 1 + + def test_weight_property(self) -> None: + """Weight should be number of qubits.""" + stab = ColorCodeStabilizer(index=0, qubits=(0, 1, 2, 3), color="red") + assert stab.weight == 4 + + def test_boundary_default_false(self) -> None: + """is_boundary should default to False.""" + stab = ColorCodeStabilizer(index=0, qubits=(0, 1), color="red") + assert stab.is_boundary is False diff --git a/python/quantum-pecos/tests/pecos/qec/test_protocols.py b/python/quantum-pecos/tests/pecos/qec/test_protocols.py new file mode 100644 index 000000000..6122375cf --- /dev/null +++ b/python/quantum-pecos/tests/pecos/qec/test_protocols.py @@ -0,0 +1,223 @@ +# Copyright 2024 The PECOS Developers +# Licensed under the Apache License, Version 2.0 + +"""Tests for pecos.qec.protocols module.""" + +from dataclasses import FrozenInstanceError + +import pytest +from pecos.qec.protocols import ( + InnerCodeGeometry, + MSDProtocol, + OuterCodeGeometry, + create_msd_protocol, +) + + +class TestInnerCodeGeometry: + """Tests for inner code (distance-2) geometry.""" + + def test_default_data_qubits(self) -> None: + """Inner code should use qubits 0, 1, 3, 4.""" + inner = InnerCodeGeometry() + assert inner.data_qubits == (0, 1, 3, 4) + + def test_num_data(self) -> None: + """Inner code should have 4 data qubits.""" + inner = InnerCodeGeometry() + assert inner.num_data == 4 + + def test_z_stabilizer(self) -> None: + """Z stabilizer should act on all 4 qubits.""" + inner = InnerCodeGeometry() + assert inner.z_stabilizer == (0, 3, 1, 4) # column-major order + + def test_x_stabilizers(self) -> None: + """Should have 2 X stabilizers (top and bottom rows).""" + inner = InnerCodeGeometry() + assert inner.num_x_stabilizers == 2 + assert inner.x_stabilizers == ((0, 1), (3, 4)) + + def test_num_z_stabilizers(self) -> None: + """Should have 1 Z stabilizer.""" + inner = InnerCodeGeometry() + assert inner.num_z_stabilizers == 1 + + def test_num_syndromes(self) -> None: + """Total syndromes per round should be 3 (2 X + 1 Z).""" + inner = InnerCodeGeometry() + assert inner.num_syndromes == 3 + + def test_is_frozen(self) -> None: + """InnerCodeGeometry should be immutable.""" + inner = InnerCodeGeometry() + with pytest.raises(FrozenInstanceError): + inner.data_qubits = (0, 1, 2, 3) + + +class TestOuterCodeGeometry: + """Tests for outer code (distance-3) geometry.""" + + def test_default_data_qubits(self) -> None: + """Outer code should use all 9 qubits.""" + outer = OuterCodeGeometry() + assert outer.data_qubits == (0, 1, 2, 3, 4, 5, 6, 7, 8) + + def test_num_data(self) -> None: + """Outer code should have 9 data qubits.""" + outer = OuterCodeGeometry() + assert outer.num_data == 9 + + def test_inner_qubits(self) -> None: + """Inner qubits should be 0, 1, 3, 4.""" + outer = OuterCodeGeometry() + assert outer.inner_qubits == (0, 1, 3, 4) + + def test_expansion_qubits(self) -> None: + """Expansion qubits should be 2, 5, 6, 7, 8.""" + outer = OuterCodeGeometry() + assert outer.expansion_qubits == (2, 5, 6, 7, 8) + + def test_num_expansion(self) -> None: + """Should add 5 qubits during expansion.""" + outer = OuterCodeGeometry() + assert outer.num_expansion == 5 + + def test_x_stabilizers_count(self) -> None: + """Should have 4 X stabilizers.""" + outer = OuterCodeGeometry() + assert outer.num_x_stabilizers == 4 + + def test_z_stabilizers_count(self) -> None: + """Should have 4 Z stabilizers.""" + outer = OuterCodeGeometry() + assert outer.num_z_stabilizers == 4 + + def test_num_syndromes(self) -> None: + """Total syndromes per round should be 8 (4 X + 4 Z).""" + outer = OuterCodeGeometry() + assert outer.num_syndromes == 8 + + def test_bulk_x_stabilizers(self) -> None: + """Should have 2 bulk X stabilizers (weight 4).""" + outer = OuterCodeGeometry() + bulk = outer.get_bulk_x_stabilizers() + assert len(bulk) == 2 + for stab in bulk: + assert len(stab) == 4 + + def test_boundary_x_stabilizers(self) -> None: + """Should have 2 boundary X stabilizers (weight 2).""" + outer = OuterCodeGeometry() + boundary = outer.get_boundary_x_stabilizers() + assert len(boundary) == 2 + for stab in boundary: + assert len(stab) == 2 + + def test_bulk_z_stabilizers(self) -> None: + """Should have 2 bulk Z stabilizers (weight 4).""" + outer = OuterCodeGeometry() + bulk = outer.get_bulk_z_stabilizers() + assert len(bulk) == 2 + for stab in bulk: + assert len(stab) == 4 + + def test_boundary_z_stabilizers(self) -> None: + """Should have 2 boundary Z stabilizers (weight 2).""" + outer = OuterCodeGeometry() + boundary = outer.get_boundary_z_stabilizers() + assert len(boundary) == 2 + for stab in boundary: + assert len(stab) == 2 + + def test_is_frozen(self) -> None: + """OuterCodeGeometry should be immutable.""" + outer = OuterCodeGeometry() + with pytest.raises(FrozenInstanceError): + outer.data_qubits = (0, 1, 2) + + +class TestMSDProtocol: + """Tests for MSD protocol structure.""" + + def test_default_inner_rounds(self) -> None: + """Default inner rounds should be 2.""" + msd = MSDProtocol() + assert msd.inner_rounds == 2 + + def test_default_outer_rounds(self) -> None: + """Default outer rounds should be 1.""" + msd = MSDProtocol() + assert msd.outer_rounds == 1 + + def test_total_data_qubits(self) -> None: + """Total data qubits should be 9 (same as outer code).""" + msd = MSDProtocol() + assert msd.total_data_qubits == 9 + + def test_inner_syndrome_bits(self) -> None: + """Inner syndrome bits per round should be 3.""" + msd = MSDProtocol() + assert msd.inner_syndrome_bits == 3 + + def test_outer_syndrome_bits(self) -> None: + """Outer syndrome bits per round should be 8.""" + msd = MSDProtocol() + assert msd.outer_syndrome_bits == 8 + + def test_total_inner_syndromes(self) -> None: + """Total inner syndromes should be 3 * 2 = 6.""" + msd = MSDProtocol() + assert msd.total_inner_syndromes == 6 + + def test_total_outer_syndromes(self) -> None: + """Total outer syndromes should be 8 * 1 = 8.""" + msd = MSDProtocol() + assert msd.total_outer_syndromes == 8 + + def test_expansion_prep_states(self) -> None: + """Expansion prep states should be correct.""" + msd = MSDProtocol() + prep = msd.get_expansion_prep_states() + assert prep[2] == "0" + assert prep[5] == "0" + assert prep[6] == "+" + assert prep[7] == "+" + assert prep[8] == "+" + + def test_inner_init_states(self) -> None: + """Inner init states should be correct.""" + msd = MSDProtocol() + init = msd.get_inner_init_states() + assert init[0] == "T+" + assert init[1] == "0" + assert init[3] == "+" + assert init[4] == "+" + + +class TestCreateMSDProtocol: + """Tests for create_msd_protocol factory function.""" + + def test_default_creation(self) -> None: + """Default creation should work.""" + msd = create_msd_protocol() + assert msd.inner_rounds == 2 + assert msd.outer_rounds == 1 + + def test_custom_inner_rounds(self) -> None: + """Custom inner rounds should be respected.""" + msd = create_msd_protocol(inner_rounds=3) + assert msd.inner_rounds == 3 + + def test_custom_outer_rounds(self) -> None: + """Custom outer rounds should be respected.""" + msd = create_msd_protocol(outer_rounds=2) + assert msd.outer_rounds == 2 + + def test_both_custom(self) -> None: + """Both custom parameters should be respected.""" + msd = create_msd_protocol(inner_rounds=4, outer_rounds=3) + assert msd.inner_rounds == 4 + assert msd.outer_rounds == 3 + assert msd.total_inner_syndromes == 12 + assert msd.total_outer_syndromes == 24 diff --git a/python/quantum-pecos/tests/pecos/qec/test_surface_layouts.py b/python/quantum-pecos/tests/pecos/qec/test_surface_layouts.py new file mode 100644 index 000000000..f2131162c --- /dev/null +++ b/python/quantum-pecos/tests/pecos/qec/test_surface_layouts.py @@ -0,0 +1,246 @@ +# Copyright 2024 The PECOS Developers +# Licensed under the Apache License, Version 2.0 + +"""Tests for pecos.qec.surface layout functions.""" + +import pytest +from pecos.qec.surface.layouts import ( + StabilizerSupport, + compute_x_stabilizer_supports, + compute_z_stabilizer_supports, + generate_nonrotated_surface_layout, + generate_surface_layout, + get_boundary_stabilizer_indices, + get_boundary_stabilizers, + get_bulk_stabilizer_indices, + get_bulk_stabilizers, + get_stabilizer_counts, +) + + +class TestGenerateNonrotatedSurfaceLayout: + """Tests for non-rotated surface code layout generation.""" + + def test_d3_data_qubit_count(self) -> None: + """Distance-3 non-rotated code should have 13 data qubits.""" + data, _ancilla, _polygons = generate_nonrotated_surface_layout(3, 3) + assert len(data) == 13 + + def test_d5_data_qubit_count(self) -> None: + """Distance-5 non-rotated code should have 41 data qubits.""" + data, _ancilla, _polygons = generate_nonrotated_surface_layout(5, 5) + assert len(data) == 41 + + def test_d3_total_positions(self) -> None: + """Check total positions for d=3.""" + data, ancilla, _polygons = generate_nonrotated_surface_layout(3, 3) + # 5x5 lattice = 25 total positions + assert len(data) + len(ancilla) == 25 + + def test_asymmetric_layout(self) -> None: + """Test asymmetric width/height.""" + data, ancilla, _polygons = generate_nonrotated_surface_layout(3, 5) + # 5x9 lattice + assert len(data) + len(ancilla) == 45 + + def test_data_positions_are_unique(self) -> None: + """All data positions should be unique.""" + data, _, _ = generate_nonrotated_surface_layout(5, 5) + assert len(data) == len(set(data)) + + def test_ancilla_positions_are_unique(self) -> None: + """All ancilla positions should be unique.""" + _, ancilla, _ = generate_nonrotated_surface_layout(5, 5) + assert len(ancilla) == len(set(ancilla)) + + def test_no_overlap_data_ancilla(self) -> None: + """Data and ancilla positions should not overlap.""" + data, ancilla, _ = generate_nonrotated_surface_layout(5, 5) + data_set = set(data) + ancilla_set = set(ancilla) + assert data_set.isdisjoint(ancilla_set) + + +class TestGenerateSurfaceLayout: + """Tests for rotated surface code layout generation (default).""" + + def test_d3_data_qubit_count(self) -> None: + """Distance-3 rotated code should have 9 data qubits.""" + data, _ancilla = generate_surface_layout(3, 3) + assert len(data) == 9 + + def test_d5_data_qubit_count(self) -> None: + """Distance-5 rotated code should have 25 data qubits.""" + data, _ancilla = generate_surface_layout(5, 5) + assert len(data) == 25 + + def test_d3_ancilla_count(self) -> None: + """Distance-3 rotated code should have 8 ancilla qubits.""" + _data, ancilla = generate_surface_layout(3, 3) + assert len(ancilla) == 8 + + def test_data_positions_are_unique(self) -> None: + """All data positions should be unique.""" + data, _ = generate_surface_layout(5, 5) + assert len(data) == len(set(data)) + + def test_ancilla_positions_are_unique(self) -> None: + """All ancilla positions should be unique.""" + _, ancilla = generate_surface_layout(5, 5) + assert len(ancilla) == len(set(ancilla)) + + def test_no_overlap_data_ancilla(self) -> None: + """Data and ancilla positions should not overlap.""" + data, ancilla = generate_surface_layout(5, 5) + data_set = set(data) + ancilla_set = set(ancilla) + assert data_set.isdisjoint(ancilla_set) + + def test_data_at_odd_odd_positions(self) -> None: + """In interior, data qubits should be at odd-odd positions.""" + data, _ = generate_surface_layout(5, 5) + for x, y in data: + # Interior data qubits are at odd-odd positions + if 0 < x < 10 and 0 < y < 10: + assert x % 2 == 1 + assert y % 2 == 1 + + +class TestComputeStabilizerSupports: + """Tests for stabilizer support computation.""" + + def test_x_stabilizer_count_d3(self) -> None: + """Distance-3 should have 4 X stabilizers.""" + stabs = compute_x_stabilizer_supports(3) + assert len(stabs) == 4 + + def test_z_stabilizer_count_d3(self) -> None: + """Distance-3 should have 4 Z stabilizers.""" + stabs = compute_z_stabilizer_supports(3) + assert len(stabs) == 4 + + def test_x_stabilizer_count_d5(self) -> None: + """Distance-5 should have 12 X stabilizers.""" + stabs = compute_x_stabilizer_supports(5) + assert len(stabs) == 12 + + def test_z_stabilizer_count_d5(self) -> None: + """Distance-5 should have 12 Z stabilizers.""" + stabs = compute_z_stabilizer_supports(5) + assert len(stabs) == 12 + + def test_stabilizer_indices_are_sequential(self) -> None: + """Stabilizer indices should be 0 to n-1.""" + stabs = compute_x_stabilizer_supports(5) + indices = sorted(s.index for s in stabs) + assert indices == list(range(len(stabs))) + + def test_bulk_stabilizers_have_weight_4(self) -> None: + """Non-boundary stabilizers should have weight 4.""" + stabs = compute_x_stabilizer_supports(5) + for s in stabs: + if not s.is_boundary: + assert s.weight == 4 + + def test_boundary_stabilizers_have_weight_2(self) -> None: + """Boundary stabilizers should have weight 2.""" + stabs = compute_x_stabilizer_supports(5) + for s in stabs: + if s.is_boundary: + assert s.weight == 2 + + def test_stabilizer_support_is_dataclass(self) -> None: + """StabilizerSupport should be a frozen dataclass.""" + stabs = compute_x_stabilizer_supports(3) + s = stabs[0] + assert isinstance(s, StabilizerSupport) + # Frozen dataclass should be hashable + assert hash(s) is not None + + +class TestStabilizerCategories: + """Tests for bulk/boundary stabilizer categorization.""" + + def test_stabilizer_counts_d3(self) -> None: + """Test stabilizer counts for d=3.""" + total, n_bulk, n_boundary = get_stabilizer_counts(3) + assert total == 4 + assert n_bulk == 2 + assert n_boundary == 2 + + def test_stabilizer_counts_d5(self) -> None: + """Test stabilizer counts for d=5.""" + total, n_bulk, n_boundary = get_stabilizer_counts(5) + assert total == 12 + assert n_bulk == 8 + assert n_boundary == 4 + + def test_stabilizer_counts_d7(self) -> None: + """Test stabilizer counts for d=7.""" + total, n_bulk, n_boundary = get_stabilizer_counts(7) + assert total == 24 + assert n_bulk == 18 + assert n_boundary == 6 + + def test_bulk_indices_d3(self) -> None: + """Bulk indices for d=3 should be [1, 2].""" + indices = get_bulk_stabilizer_indices(3) + assert indices == [1, 2] + + def test_boundary_indices_d3(self) -> None: + """Boundary indices for d=3 should be [0, 3].""" + indices = get_boundary_stabilizer_indices(3) + assert indices == [0, 3] + + def test_bulk_indices_d5(self) -> None: + """Bulk indices for d=5.""" + indices = get_bulk_stabilizer_indices(5) + assert len(indices) == 8 + assert indices == list(range(2, 10)) + + def test_boundary_indices_d5(self) -> None: + """Boundary indices for d=5.""" + indices = get_boundary_stabilizer_indices(5) + assert len(indices) == 4 + assert indices == [0, 1, 10, 11] + + def test_bulk_plus_boundary_equals_total(self) -> None: + """Bulk + boundary indices should cover all stabilizers.""" + for d in [3, 5, 7]: + bulk = get_bulk_stabilizer_indices(d) + boundary = get_boundary_stabilizer_indices(d) + total, _, _ = get_stabilizer_counts(d) + assert len(bulk) + len(boundary) == total + assert set(bulk).isdisjoint(set(boundary)) + + def test_get_bulk_stabilizers_x(self) -> None: + """Get bulk X stabilizers.""" + bulk = get_bulk_stabilizers(5, "X") + assert len(bulk) == 8 + for s in bulk: + assert not s.is_boundary + assert s.weight == 4 + + def test_get_boundary_stabilizers_x(self) -> None: + """Get boundary X stabilizers.""" + boundary = get_boundary_stabilizers(5, "X") + assert len(boundary) == 4 + for s in boundary: + assert s.is_boundary + assert s.weight == 2 + + def test_get_bulk_stabilizers_z(self) -> None: + """Get bulk Z stabilizers.""" + bulk = get_bulk_stabilizers(5, "Z") + assert len(bulk) == 8 + for s in bulk: + assert not s.is_boundary + assert s.weight == 4 + + def test_get_boundary_stabilizers_z(self) -> None: + """Get boundary Z stabilizers.""" + boundary = get_boundary_stabilizers(5, "Z") + assert len(boundary) == 4 + for s in boundary: + assert s.is_boundary + assert s.weight == 2 diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/examples/test_logical_steane_code_program.py b/python/quantum-pecos/tests/pecos/regression/test_qasm/examples/test_logical_steane_code_program.py index 2150a9c2a..87fb61868 100644 --- a/python/quantum-pecos/tests/pecos/regression/test_qasm/examples/test_logical_steane_code_program.py +++ b/python/quantum-pecos/tests/pecos/regression/test_qasm/examples/test_logical_steane_code_program.py @@ -13,8 +13,8 @@ from collections.abc import Callable -from pecos.qeclib.steane.steane_class import Steane from pecos.slr import Barrier, CReg, If, Main +from pecos.slr.qeclib.steane.steane_class import Steane def telep(prep_basis: str, meas_basis: str) -> Main: diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/qubit/test_measures.py b/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/qubit/test_measures.py index 72cba1b43..a2a56dd00 100644 --- a/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/qubit/test_measures.py +++ b/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/qubit/test_measures.py @@ -13,8 +13,8 @@ from collections.abc import Callable -from pecos.qeclib import qubit from pecos.slr import CReg, QReg +from pecos.slr.qeclib import qubit def test_Measure(compare_qasm: Callable[..., None]) -> None: diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/qubit/test_preps.py b/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/qubit/test_preps.py index 67a772760..fe8a718af 100644 --- a/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/qubit/test_preps.py +++ b/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/qubit/test_preps.py @@ -13,8 +13,8 @@ from collections.abc import Callable -from pecos.qeclib import qubit from pecos.slr import QReg +from pecos.slr.qeclib import qubit def test_Prep(compare_qasm: Callable[..., None]) -> None: diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/qubit/test_rots.py b/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/qubit/test_rots.py index 37f4f6e2c..80b118f47 100644 --- a/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/qubit/test_rots.py +++ b/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/qubit/test_rots.py @@ -14,8 +14,8 @@ from collections.abc import Callable import pecos as pc -from pecos.qeclib import qubit from pecos.slr import QReg +from pecos.slr.qeclib import qubit def test_RX(compare_qasm: Callable[..., None]) -> None: diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/qubit/test_sq_face_rots.py b/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/qubit/test_sq_face_rots.py index fe2c6ebb1..a3900323a 100644 --- a/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/qubit/test_sq_face_rots.py +++ b/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/qubit/test_sq_face_rots.py @@ -13,8 +13,8 @@ from collections.abc import Callable -from pecos.qeclib import qubit from pecos.slr import QReg +from pecos.slr.qeclib import qubit def test_F(compare_qasm: Callable[..., None]) -> None: diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/qubit/test_sq_hadamards.py b/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/qubit/test_sq_hadamards.py index 7b7a47f47..b28eb1099 100644 --- a/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/qubit/test_sq_hadamards.py +++ b/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/qubit/test_sq_hadamards.py @@ -13,8 +13,8 @@ from collections.abc import Callable -from pecos.qeclib import qubit from pecos.slr import QReg +from pecos.slr.qeclib import qubit def test_H(compare_qasm: Callable[..., None]) -> None: diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/qubit/test_sq_noncliffords.py b/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/qubit/test_sq_noncliffords.py index 767d41dd1..4b2fc6880 100644 --- a/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/qubit/test_sq_noncliffords.py +++ b/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/qubit/test_sq_noncliffords.py @@ -13,8 +13,8 @@ from collections.abc import Callable -from pecos.qeclib import qubit from pecos.slr import QReg +from pecos.slr.qeclib import qubit def test_T(compare_qasm: Callable[..., None]) -> None: diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/qubit/test_sq_paulis.py b/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/qubit/test_sq_paulis.py index c8cb7c248..b07011158 100644 --- a/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/qubit/test_sq_paulis.py +++ b/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/qubit/test_sq_paulis.py @@ -13,8 +13,8 @@ from collections.abc import Callable -from pecos.qeclib import qubit from pecos.slr import QReg +from pecos.slr.qeclib import qubit def test_X(compare_qasm: Callable[..., None]) -> None: diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/qubit/test_sq_sqrt_paulis.py b/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/qubit/test_sq_sqrt_paulis.py index 45de95563..38ed32651 100644 --- a/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/qubit/test_sq_sqrt_paulis.py +++ b/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/qubit/test_sq_sqrt_paulis.py @@ -13,8 +13,8 @@ from collections.abc import Callable -from pecos.qeclib import qubit from pecos.slr import QReg +from pecos.slr.qeclib import qubit def test_SX(compare_qasm: Callable[..., None]) -> None: diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/qubit/test_tq_cliffords.py b/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/qubit/test_tq_cliffords.py index 5bef4b98c..fcdbf3fb3 100644 --- a/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/qubit/test_tq_cliffords.py +++ b/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/qubit/test_tq_cliffords.py @@ -13,8 +13,8 @@ from collections.abc import Callable -from pecos.qeclib import qubit from pecos.slr import QReg +from pecos.slr.qeclib import qubit def test_CX(compare_qasm: Callable[..., None]) -> None: diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/qubit/test_tq_noncliffords.py b/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/qubit/test_tq_noncliffords.py index 837ee6e41..0b27309a6 100644 --- a/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/qubit/test_tq_noncliffords.py +++ b/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/qubit/test_tq_noncliffords.py @@ -13,8 +13,8 @@ from collections.abc import Callable -from pecos.qeclib import qubit from pecos.slr import QReg +from pecos.slr.qeclib import qubit def test_CH(compare_qasm: Callable[..., None]) -> None: diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/decoders/test_lookup.py b/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/decoders/test_lookup.py index 790cdbc2a..3eda944fa 100644 --- a/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/decoders/test_lookup.py +++ b/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/decoders/test_lookup.py @@ -13,12 +13,12 @@ from collections.abc import Callable -from pecos.qeclib.steane.decoders.lookup import ( +from pecos.slr import CReg, QReg +from pecos.slr.qeclib.steane.decoders.lookup import ( FlagLookupQASM, FlagLookupQASMActiveCorrectionX, FlagLookupQASMActiveCorrectionZ, ) -from pecos.slr import CReg, QReg def test_FlagLookupQASM(compare_qasm: Callable[..., None]) -> None: diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/gates_sq/test_face_rots.py b/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/gates_sq/test_face_rots.py index a03e85e0f..2be6a1072 100644 --- a/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/gates_sq/test_face_rots.py +++ b/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/gates_sq/test_face_rots.py @@ -13,8 +13,8 @@ from collections.abc import Callable -from pecos.qeclib.steane.gates_sq.face_rots import F, Fdg from pecos.slr import QReg +from pecos.slr.qeclib.steane.gates_sq.face_rots import F, Fdg def test_F(compare_qasm: Callable[..., None]) -> None: diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/gates_sq/test_hadamards.py b/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/gates_sq/test_hadamards.py index 6190f805c..563aedd65 100644 --- a/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/gates_sq/test_hadamards.py +++ b/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/gates_sq/test_hadamards.py @@ -13,8 +13,8 @@ from collections.abc import Callable -from pecos.qeclib.steane.gates_sq.hadamards import H from pecos.slr import QReg +from pecos.slr.qeclib.steane.gates_sq.hadamards import H def test_H(compare_qasm: Callable[..., None]) -> None: diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/gates_sq/test_paulis.py b/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/gates_sq/test_paulis.py index e74cd80d5..4f81924c3 100644 --- a/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/gates_sq/test_paulis.py +++ b/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/gates_sq/test_paulis.py @@ -13,8 +13,8 @@ from collections.abc import Callable -from pecos.qeclib.steane.gates_sq.paulis import X, Y, Z from pecos.slr import QReg +from pecos.slr.qeclib.steane.gates_sq.paulis import X, Y, Z def test_X(compare_qasm: Callable[..., None]) -> None: diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/gates_sq/test_sqrt_paulis.py b/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/gates_sq/test_sqrt_paulis.py index 89fd6a439..8cadc351c 100644 --- a/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/gates_sq/test_sqrt_paulis.py +++ b/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/gates_sq/test_sqrt_paulis.py @@ -13,8 +13,8 @@ from collections.abc import Callable -from pecos.qeclib.steane.gates_sq.sqrt_paulis import SX, SY, SZ, SXdg, SYdg, SZdg from pecos.slr import QReg +from pecos.slr.qeclib.steane.gates_sq.sqrt_paulis import SX, SY, SZ, SXdg, SYdg, SZdg def test_SX(compare_qasm: Callable[..., None]) -> None: diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/gates_tq/test_transversal_tq.py b/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/gates_tq/test_transversal_tq.py index 1e22b1635..d5915efb1 100644 --- a/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/gates_tq/test_transversal_tq.py +++ b/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/gates_tq/test_transversal_tq.py @@ -13,8 +13,8 @@ from collections.abc import Callable -from pecos.qeclib.steane.gates_tq.transversal_tq import CX, CY, CZ, SZZ from pecos.slr import QReg +from pecos.slr.qeclib.steane.gates_tq.transversal_tq import CX, CY, CZ, SZZ def test_CX(compare_qasm: Callable[..., None]) -> None: diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/meas/test_destructive_meas.py b/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/meas/test_destructive_meas.py index 3f71bc3eb..e202da4ef 100644 --- a/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/meas/test_destructive_meas.py +++ b/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/meas/test_destructive_meas.py @@ -13,7 +13,8 @@ from collections.abc import Callable -from pecos.qeclib.steane.meas.destructive_meas import ( +from pecos.slr import CReg, QReg +from pecos.slr.qeclib.steane.meas.destructive_meas import ( MeasDecode, Measure, MeasureX, @@ -21,7 +22,6 @@ MeasureZ, ProcessMeas, ) -from pecos.slr import CReg, QReg def test_MeasureX(compare_qasm: Callable[..., None]) -> None: diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/meas/test_measure_x.py b/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/meas/test_measure_x.py index 1779463d7..c7f611ccc 100644 --- a/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/meas/test_measure_x.py +++ b/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/meas/test_measure_x.py @@ -13,8 +13,8 @@ from collections.abc import Callable -from pecos.qeclib.steane.meas.measure_x import NoFlagMeasureX from pecos.slr import CReg, QReg +from pecos.slr.qeclib.steane.meas.measure_x import NoFlagMeasureX def test_MeasureX(compare_qasm: Callable[..., None]) -> None: diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/meas/test_measure_z.py b/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/meas/test_measure_z.py index 7a4b1e317..768fdd30f 100644 --- a/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/meas/test_measure_z.py +++ b/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/meas/test_measure_z.py @@ -13,8 +13,8 @@ from collections.abc import Callable -from pecos.qeclib.steane.meas.measure_z import NoFlagMeasureZ from pecos.slr import CReg, QReg +from pecos.slr.qeclib.steane.meas.measure_z import NoFlagMeasureZ def test_MeasureX(compare_qasm: Callable[..., None]) -> None: diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/preps/test_encoding_circ.py b/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/preps/test_encoding_circ.py index 15fe09659..239a35299 100644 --- a/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/preps/test_encoding_circ.py +++ b/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/preps/test_encoding_circ.py @@ -13,8 +13,8 @@ from collections.abc import Callable -from pecos.qeclib.steane.preps.encoding_circ import EncodingCircuit from pecos.slr import QReg +from pecos.slr.qeclib.steane.preps.encoding_circ import EncodingCircuit def test_EncodingCircuit(compare_qasm: Callable[..., None]) -> None: diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/preps/test_pauli_states.py b/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/preps/test_pauli_states.py index f5a5775e0..b51375fb0 100644 --- a/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/preps/test_pauli_states.py +++ b/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/preps/test_pauli_states.py @@ -13,14 +13,14 @@ from collections.abc import Callable -from pecos.qeclib.steane.preps.pauli_states import ( +from pecos.slr import CReg, QReg +from pecos.slr.qeclib.steane.preps.pauli_states import ( LogZeroRot, PrepEncodingFTZero, PrepEncodingNonFTZero, PrepRUS, PrepZeroVerify, ) -from pecos.slr import CReg, QReg def test_PrepEncodingNonFTZero(compare_qasm: Callable[..., None]) -> None: diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/preps/test_plus_h_state.py b/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/preps/test_plus_h_state.py index 97c05bf4d..0b3b9c2a2 100644 --- a/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/preps/test_plus_h_state.py +++ b/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/preps/test_plus_h_state.py @@ -13,8 +13,8 @@ from collections.abc import Callable -from pecos.qeclib.steane.preps.plus_h_state import PrepHStateFT from pecos.slr import CReg, QReg +from pecos.slr.qeclib.steane.preps.plus_h_state import PrepHStateFT def test_PrepHStateFT(compare_qasm: Callable[..., None]) -> None: diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/preps/test_t_plus_state.py b/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/preps/test_t_plus_state.py index f13cc5a8d..bdb781652 100644 --- a/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/preps/test_t_plus_state.py +++ b/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/preps/test_t_plus_state.py @@ -13,13 +13,13 @@ from collections.abc import Callable -from pecos.qeclib.steane.preps.t_plus_state import ( +from pecos.slr import CReg, QReg +from pecos.slr.qeclib.steane.preps.t_plus_state import ( PrepEncodeTDagPlusNonFT, PrepEncodeTPlusFT, PrepEncodeTPlusFTRUS, PrepEncodeTPlusNonFT, ) -from pecos.slr import CReg, QReg def test_PrepEncodeTPlusNonFT(compare_qasm: Callable[..., None]) -> None: diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/qec/test_qec_3parallel.py b/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/qec/test_qec_3parallel.py index 5c436ee41..4102f5d34 100644 --- a/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/qec/test_qec_3parallel.py +++ b/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/qec/test_qec_3parallel.py @@ -13,8 +13,8 @@ from collections.abc import Callable -from pecos.qeclib.steane.qec.qec_3parallel import ParallelFlagQECActiveCorrection from pecos.slr import CReg, QReg +from pecos.slr.qeclib.steane.qec.qec_3parallel import ParallelFlagQECActiveCorrection def test_ParallelFlagQECActiveCorrection(compare_qasm: Callable[..., None]) -> None: diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/syn_extract/test_six_check_nonflagging.py b/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/syn_extract/test_six_check_nonflagging.py index 87b5c28f3..a07004242 100644 --- a/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/syn_extract/test_six_check_nonflagging.py +++ b/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/syn_extract/test_six_check_nonflagging.py @@ -13,8 +13,8 @@ from collections.abc import Callable -from pecos.qeclib.steane.syn_extract.six_check_nonflagging import SixUnflaggedSyn from pecos.slr import CReg, QReg +from pecos.slr.qeclib.steane.syn_extract.six_check_nonflagging import SixUnflaggedSyn def test_SixUnflaggedSyn(compare_qasm: Callable[..., None]) -> None: diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/syn_extract/test_three_parallel_flagging.py b/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/syn_extract/test_three_parallel_flagging.py index bedc007b4..9f7b9c951 100644 --- a/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/syn_extract/test_three_parallel_flagging.py +++ b/python/quantum-pecos/tests/pecos/regression/test_qasm/pecos/qeclib/steane/syn_extract/test_three_parallel_flagging.py @@ -13,11 +13,11 @@ from collections.abc import Callable -from pecos.qeclib.steane.syn_extract.three_parallel_flagging import ( +from pecos.slr import CReg, QReg +from pecos.slr.qeclib.steane.syn_extract.three_parallel_flagging import ( ThreeParallelFlaggingXZZ, ThreeParallelFlaggingZXX, ) -from pecos.slr import CReg, QReg def test_ThreeParallelFlaggingXZZ(compare_qasm: Callable[..., None]) -> None: diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/random_cases/test_control_flow.py b/python/quantum-pecos/tests/pecos/regression/test_qasm/random_cases/test_control_flow.py index 9fd7b7620..b00b9b346 100644 --- a/python/quantum-pecos/tests/pecos/regression/test_qasm/random_cases/test_control_flow.py +++ b/python/quantum-pecos/tests/pecos/regression/test_qasm/random_cases/test_control_flow.py @@ -13,8 +13,8 @@ from collections.abc import Callable -from pecos.qeclib import qubit as qb from pecos.slr import Block, CReg, If, Main, Parallel, QReg, Repeat +from pecos.slr.qeclib import qubit as qb def test_phys_teleport(compare_qasm: Callable[..., None]) -> None: diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/random_cases/test_permute.py b/python/quantum-pecos/tests/pecos/regression/test_qasm/random_cases/test_permute.py index 86fcea4e7..8df835e7d 100644 --- a/python/quantum-pecos/tests/pecos/regression/test_qasm/random_cases/test_permute.py +++ b/python/quantum-pecos/tests/pecos/regression/test_qasm/random_cases/test_permute.py @@ -11,8 +11,8 @@ """Testing SLR->QASM permute cases.""" -from pecos.qeclib.steane.steane_class import Steane from pecos.slr import Block, CReg, Main, Permute, SlrConverter +from pecos.slr.qeclib.steane.steane_class import Steane def test_permute1() -> None: diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/random_cases/test_slr_phys.py b/python/quantum-pecos/tests/pecos/regression/test_qasm/random_cases/test_slr_phys.py index 44a29c6b0..f0a61fb38 100644 --- a/python/quantum-pecos/tests/pecos/regression/test_qasm/random_cases/test_slr_phys.py +++ b/python/quantum-pecos/tests/pecos/regression/test_qasm/random_cases/test_slr_phys.py @@ -1,8 +1,6 @@ """Test SLR to physical quantum circuit compilation for various cases.""" import pytest -from pecos.qeclib import qubit as p -from pecos.qeclib.steane.steane_class import Steane from pecos.slr import ( Barrier, Bit, @@ -17,6 +15,8 @@ Repeat, SlrConverter, ) +from pecos.slr.qeclib import qubit as p +from pecos.slr.qeclib.steane.steane_class import Steane # TODO: Remove reference to hqslib1.inc... better yet, don't have tests on qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.measures.Measure.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.measures.Measure.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.measures.Measure.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.measures.Measure.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.preps.Prep.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.preps.Prep.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.preps.Prep.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.preps.Prep.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.rots.RXGate.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.rots.RXGate.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.rots.RXGate.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.rots.RXGate.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.rots.RYGate.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.rots.RYGate.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.rots.RYGate.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.rots.RYGate.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.rots.RZGate.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.rots.RZGate.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.rots.RZGate.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.rots.RZGate.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.rots.RZZGate.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.rots.RZZGate.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.rots.RZZGate.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.rots.RZZGate.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.sq_face_rots.F.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.sq_face_rots.F.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.sq_face_rots.F.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.sq_face_rots.F.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.sq_face_rots.F4.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.sq_face_rots.F4.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.sq_face_rots.F4.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.sq_face_rots.F4.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.sq_face_rots.F4dg.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.sq_face_rots.F4dg.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.sq_face_rots.F4dg.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.sq_face_rots.F4dg.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.sq_face_rots.Fdg.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.sq_face_rots.Fdg.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.sq_face_rots.Fdg.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.sq_face_rots.Fdg.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.sq_hadamards.H.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.sq_hadamards.H.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.sq_hadamards.H.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.sq_hadamards.H.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.sq_noncliffords.T.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.sq_noncliffords.T.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.sq_noncliffords.T.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.sq_noncliffords.T.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.sq_noncliffords.Tdg.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.sq_noncliffords.Tdg.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.sq_noncliffords.Tdg.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.sq_noncliffords.Tdg.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.sq_paulis.X.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.sq_paulis.X.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.sq_paulis.X.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.sq_paulis.X.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.sq_paulis.Y.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.sq_paulis.Y.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.sq_paulis.Y.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.sq_paulis.Y.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.sq_paulis.Z.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.sq_paulis.Z.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.sq_paulis.Z.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.sq_paulis.Z.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.sq_sqrt_paulis.SX.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.sq_sqrt_paulis.SX.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.sq_sqrt_paulis.SX.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.sq_sqrt_paulis.SX.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.sq_sqrt_paulis.SXdg.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.sq_sqrt_paulis.SXdg.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.sq_sqrt_paulis.SXdg.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.sq_sqrt_paulis.SXdg.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.sq_sqrt_paulis.SY.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.sq_sqrt_paulis.SY.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.sq_sqrt_paulis.SY.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.sq_sqrt_paulis.SY.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.sq_sqrt_paulis.SYdg.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.sq_sqrt_paulis.SYdg.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.sq_sqrt_paulis.SYdg.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.sq_sqrt_paulis.SYdg.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.sq_sqrt_paulis.SZ.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.sq_sqrt_paulis.SZ.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.sq_sqrt_paulis.SZ.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.sq_sqrt_paulis.SZ.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.sq_sqrt_paulis.SZdg.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.sq_sqrt_paulis.SZdg.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.sq_sqrt_paulis.SZdg.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.sq_sqrt_paulis.SZdg.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.tq_cliffords.CX.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.tq_cliffords.CX.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.tq_cliffords.CX.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.tq_cliffords.CX.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.tq_cliffords.CY.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.tq_cliffords.CY.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.tq_cliffords.CY.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.tq_cliffords.CY.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.tq_cliffords.CZ.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.tq_cliffords.CZ.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.tq_cliffords.CZ.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.tq_cliffords.CZ.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.tq_cliffords.SXX.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.tq_cliffords.SXX.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.tq_cliffords.SXX.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.tq_cliffords.SXX.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.tq_cliffords.SXXdg.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.tq_cliffords.SXXdg.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.tq_cliffords.SXXdg.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.tq_cliffords.SXXdg.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.tq_cliffords.SYY.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.tq_cliffords.SYY.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.tq_cliffords.SYY.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.tq_cliffords.SYY.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.tq_cliffords.SYYdg.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.tq_cliffords.SYYdg.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.tq_cliffords.SYYdg.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.tq_cliffords.SYYdg.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.tq_cliffords.SZZ.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.tq_cliffords.SZZ.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.tq_cliffords.SZZ.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.tq_cliffords.SZZ.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.tq_cliffords.SZZdg.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.tq_cliffords.SZZdg.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.tq_cliffords.SZZdg.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.tq_cliffords.SZZdg.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.tq_noncliffords.CH.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.tq_noncliffords.CH.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.qubit.tq_noncliffords.CH.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.qubit.tq_noncliffords.CH.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.decoders.lookup.FlagLookupQASMActiveCorrectionX_None.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.decoders.lookup.FlagLookupQASMActiveCorrectionX_None.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.decoders.lookup.FlagLookupQASMActiveCorrectionX_None.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.decoders.lookup.FlagLookupQASMActiveCorrectionX_None.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.decoders.lookup.FlagLookupQASMActiveCorrectionX_pf_copy_test.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.decoders.lookup.FlagLookupQASMActiveCorrectionX_pf_copy_test.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.decoders.lookup.FlagLookupQASMActiveCorrectionX_pf_copy_test.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.decoders.lookup.FlagLookupQASMActiveCorrectionX_pf_copy_test.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.decoders.lookup.FlagLookupQASMActiveCorrectionZ_None.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.decoders.lookup.FlagLookupQASMActiveCorrectionZ_None.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.decoders.lookup.FlagLookupQASMActiveCorrectionZ_None.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.decoders.lookup.FlagLookupQASMActiveCorrectionZ_None.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.decoders.lookup.FlagLookupQASMActiveCorrectionZ_pf_copy_test.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.decoders.lookup.FlagLookupQASMActiveCorrectionZ_pf_copy_test.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.decoders.lookup.FlagLookupQASMActiveCorrectionZ_pf_copy_test.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.decoders.lookup.FlagLookupQASMActiveCorrectionZ_pf_copy_test.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.decoders.lookup.FlagLookupQASM_X.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.decoders.lookup.FlagLookupQASM_X.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.decoders.lookup.FlagLookupQASM_X.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.decoders.lookup.FlagLookupQASM_X.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.decoders.lookup.FlagLookupQASM_Y.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.decoders.lookup.FlagLookupQASM_Y.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.decoders.lookup.FlagLookupQASM_Y.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.decoders.lookup.FlagLookupQASM_Y.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.decoders.lookup.FlagLookupQASM_Z.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.decoders.lookup.FlagLookupQASM_Z.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.decoders.lookup.FlagLookupQASM_Z.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.decoders.lookup.FlagLookupQASM_Z.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.gates_sq.face_rots.F.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.gates_sq.face_rots.F.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.gates_sq.face_rots.F.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.gates_sq.face_rots.F.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.gates_sq.face_rots.Fdg.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.gates_sq.face_rots.Fdg.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.gates_sq.face_rots.Fdg.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.gates_sq.face_rots.Fdg.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.gates_sq.hadamards.H.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.gates_sq.hadamards.H.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.gates_sq.hadamards.H.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.gates_sq.hadamards.H.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.gates_sq.paulis.X.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.gates_sq.paulis.X.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.gates_sq.paulis.X.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.gates_sq.paulis.X.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.gates_sq.paulis.Y.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.gates_sq.paulis.Y.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.gates_sq.paulis.Y.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.gates_sq.paulis.Y.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.gates_sq.paulis.Z.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.gates_sq.paulis.Z.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.gates_sq.paulis.Z.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.gates_sq.paulis.Z.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.gates_sq.sqrt_paulis.SX.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.gates_sq.sqrt_paulis.SX.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.gates_sq.sqrt_paulis.SX.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.gates_sq.sqrt_paulis.SX.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.gates_sq.sqrt_paulis.SXdg.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.gates_sq.sqrt_paulis.SXdg.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.gates_sq.sqrt_paulis.SXdg.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.gates_sq.sqrt_paulis.SXdg.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.gates_sq.sqrt_paulis.SY.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.gates_sq.sqrt_paulis.SY.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.gates_sq.sqrt_paulis.SY.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.gates_sq.sqrt_paulis.SY.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.gates_sq.sqrt_paulis.SYdg.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.gates_sq.sqrt_paulis.SYdg.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.gates_sq.sqrt_paulis.SYdg.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.gates_sq.sqrt_paulis.SYdg.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.gates_sq.sqrt_paulis.SZ.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.gates_sq.sqrt_paulis.SZ.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.gates_sq.sqrt_paulis.SZ.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.gates_sq.sqrt_paulis.SZ.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.gates_sq.sqrt_paulis.SZdg.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.gates_sq.sqrt_paulis.SZdg.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.gates_sq.sqrt_paulis.SZdg.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.gates_sq.sqrt_paulis.SZdg.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.gates_tq.transversal_tq.CX_False.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.gates_tq.transversal_tq.CX_False.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.gates_tq.transversal_tq.CX_False.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.gates_tq.transversal_tq.CX_False.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.gates_tq.transversal_tq.CX_True.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.gates_tq.transversal_tq.CX_True.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.gates_tq.transversal_tq.CX_True.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.gates_tq.transversal_tq.CX_True.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.gates_tq.transversal_tq.CY.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.gates_tq.transversal_tq.CY.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.gates_tq.transversal_tq.CY.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.gates_tq.transversal_tq.CY.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.gates_tq.transversal_tq.CZ.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.gates_tq.transversal_tq.CZ.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.gates_tq.transversal_tq.CZ.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.gates_tq.transversal_tq.CZ.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.gates_tq.transversal_tq.SZZ.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.gates_tq.transversal_tq.SZZ.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.gates_tq.transversal_tq.SZZ.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.gates_tq.transversal_tq.SZZ.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.meas.destructive_meas.MeasureX_False.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.meas.destructive_meas.MeasureX_False.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.meas.destructive_meas.MeasureX_False.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.meas.destructive_meas.MeasureX_False.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.meas.destructive_meas.MeasureX_True.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.meas.destructive_meas.MeasureX_True.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.meas.destructive_meas.MeasureX_True.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.meas.destructive_meas.MeasureX_True.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.meas.destructive_meas.MeasureY_False.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.meas.destructive_meas.MeasureY_False.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.meas.destructive_meas.MeasureY_False.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.meas.destructive_meas.MeasureY_False.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.meas.destructive_meas.MeasureY_True.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.meas.destructive_meas.MeasureY_True.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.meas.destructive_meas.MeasureY_True.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.meas.destructive_meas.MeasureY_True.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.meas.destructive_meas.MeasureZ_False.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.meas.destructive_meas.MeasureZ_False.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.meas.destructive_meas.MeasureZ_False.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.meas.destructive_meas.MeasureZ_False.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.meas.destructive_meas.MeasureZ_True.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.meas.destructive_meas.MeasureZ_True.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.meas.destructive_meas.MeasureZ_True.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.meas.destructive_meas.MeasureZ_True.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.meas.destructive_meas.Measure_X.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.meas.destructive_meas.Measure_X.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.meas.destructive_meas.Measure_X.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.meas.destructive_meas.Measure_X.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.meas.destructive_meas.Measure_Y.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.meas.destructive_meas.Measure_Y.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.meas.destructive_meas.Measure_Y.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.meas.destructive_meas.Measure_Y.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.meas.destructive_meas.Measure_Z.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.meas.destructive_meas.Measure_Z.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.meas.destructive_meas.Measure_Z.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.meas.destructive_meas.Measure_Z.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.meas.destructive_meas.ProcessMeas_X_xy.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.meas.destructive_meas.ProcessMeas_X_xy.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.meas.destructive_meas.ProcessMeas_X_xy.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.meas.destructive_meas.ProcessMeas_X_xy.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.meas.destructive_meas.ProcessMeas_X_xz.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.meas.destructive_meas.ProcessMeas_X_xz.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.meas.destructive_meas.ProcessMeas_X_xz.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.meas.destructive_meas.ProcessMeas_X_xz.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.meas.destructive_meas.ProcessMeas_X_yz.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.meas.destructive_meas.ProcessMeas_X_yz.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.meas.destructive_meas.ProcessMeas_X_yz.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.meas.destructive_meas.ProcessMeas_X_yz.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.meas.destructive_meas.ProcessMeas_Y_xy.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.meas.destructive_meas.ProcessMeas_Y_xy.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.meas.destructive_meas.ProcessMeas_Y_xy.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.meas.destructive_meas.ProcessMeas_Y_xy.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.meas.destructive_meas.ProcessMeas_Y_xz.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.meas.destructive_meas.ProcessMeas_Y_xz.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.meas.destructive_meas.ProcessMeas_Y_xz.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.meas.destructive_meas.ProcessMeas_Y_xz.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.meas.destructive_meas.ProcessMeas_Y_yz.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.meas.destructive_meas.ProcessMeas_Y_yz.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.meas.destructive_meas.ProcessMeas_Y_yz.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.meas.destructive_meas.ProcessMeas_Y_yz.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.meas.destructive_meas.ProcessMeas_Z_xy.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.meas.destructive_meas.ProcessMeas_Z_xy.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.meas.destructive_meas.ProcessMeas_Z_xy.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.meas.destructive_meas.ProcessMeas_Z_xy.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.meas.destructive_meas.ProcessMeas_Z_xz.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.meas.destructive_meas.ProcessMeas_Z_xz.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.meas.destructive_meas.ProcessMeas_Z_xz.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.meas.destructive_meas.ProcessMeas_Z_xz.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.meas.destructive_meas.ProcessMeas_Z_yz.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.meas.destructive_meas.ProcessMeas_Z_yz.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.meas.destructive_meas.ProcessMeas_Z_yz.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.meas.destructive_meas.ProcessMeas_Z_yz.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.meas.measure_x.NoFlagMeasureX.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.meas.measure_x.NoFlagMeasureX.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.meas.measure_x.NoFlagMeasureX.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.meas.measure_x.NoFlagMeasureX.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.meas.measure_z.NoFlagMeasureZ.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.meas.measure_z.NoFlagMeasureZ.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.meas.measure_z.NoFlagMeasureZ.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.meas.measure_z.NoFlagMeasureZ.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.encoding_circ.EncodingCircuit.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.encoding_circ.EncodingCircuit.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.encoding_circ.EncodingCircuit.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.encoding_circ.EncodingCircuit.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.encoding_circ.EncodingCircuit2.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.encoding_circ.EncodingCircuit2.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.encoding_circ.EncodingCircuit2.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.encoding_circ.EncodingCircuit2.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.LogZeroRot_+X.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.LogZeroRot_+X.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.LogZeroRot_+X.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.LogZeroRot_+X.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.LogZeroRot_+Y.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.LogZeroRot_+Y.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.LogZeroRot_+Y.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.LogZeroRot_+Y.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.LogZeroRot_+Z.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.LogZeroRot_+Z.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.LogZeroRot_+Z.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.LogZeroRot_+Z.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.LogZeroRot_-X.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.LogZeroRot_-X.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.LogZeroRot_-X.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.LogZeroRot_-X.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.LogZeroRot_-Y.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.LogZeroRot_-Y.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.LogZeroRot_-Y.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.LogZeroRot_-Y.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.LogZeroRot_-Z.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.LogZeroRot_-Z.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.LogZeroRot_-Z.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.LogZeroRot_-Z.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepEncodingFTZero_False.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepEncodingFTZero_False.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepEncodingFTZero_False.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepEncodingFTZero_False.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepEncodingFTZero_True.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepEncodingFTZero_True.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepEncodingFTZero_True.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepEncodingFTZero_True.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepEncodingNonFTZero.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepEncodingNonFTZero.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepEncodingNonFTZero.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepEncodingNonFTZero.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_1_+X_False.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_1_+X_False.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_1_+X_False.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_1_+X_False.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_1_+X_True.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_1_+X_True.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_1_+X_True.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_1_+X_True.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_1_+Y_False.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_1_+Y_False.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_1_+Y_False.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_1_+Y_False.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_1_+Y_True.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_1_+Y_True.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_1_+Y_True.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_1_+Y_True.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_1_+Z_False.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_1_+Z_False.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_1_+Z_False.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_1_+Z_False.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_1_+Z_True.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_1_+Z_True.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_1_+Z_True.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_1_+Z_True.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_1_-X_False.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_1_-X_False.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_1_-X_False.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_1_-X_False.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_1_-X_True.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_1_-X_True.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_1_-X_True.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_1_-X_True.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_1_-Y_False.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_1_-Y_False.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_1_-Y_False.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_1_-Y_False.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_1_-Y_True.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_1_-Y_True.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_1_-Y_True.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_1_-Y_True.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_1_-Z_False.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_1_-Z_False.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_1_-Z_False.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_1_-Z_False.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_1_-Z_True.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_1_-Z_True.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_1_-Z_True.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_1_-Z_True.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_2_+X_False.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_2_+X_False.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_2_+X_False.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_2_+X_False.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_2_+X_True.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_2_+X_True.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_2_+X_True.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_2_+X_True.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_2_+Y_False.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_2_+Y_False.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_2_+Y_False.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_2_+Y_False.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_2_+Y_True.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_2_+Y_True.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_2_+Y_True.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_2_+Y_True.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_2_+Z_False.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_2_+Z_False.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_2_+Z_False.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_2_+Z_False.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_2_+Z_True.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_2_+Z_True.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_2_+Z_True.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_2_+Z_True.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_2_-X_False.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_2_-X_False.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_2_-X_False.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_2_-X_False.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_2_-X_True.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_2_-X_True.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_2_-X_True.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_2_-X_True.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_2_-Y_False.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_2_-Y_False.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_2_-Y_False.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_2_-Y_False.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_2_-Y_True.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_2_-Y_True.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_2_-Y_True.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_2_-Y_True.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_2_-Z_False.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_2_-Z_False.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_2_-Z_False.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_2_-Z_False.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_2_-Z_True.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_2_-Z_True.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_2_-Z_True.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_2_-Z_True.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_3_+X_False.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_3_+X_False.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_3_+X_False.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_3_+X_False.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_3_+X_True.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_3_+X_True.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_3_+X_True.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_3_+X_True.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_3_+Y_False.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_3_+Y_False.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_3_+Y_False.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_3_+Y_False.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_3_+Y_True.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_3_+Y_True.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_3_+Y_True.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_3_+Y_True.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_3_+Z_False.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_3_+Z_False.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_3_+Z_False.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_3_+Z_False.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_3_+Z_True.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_3_+Z_True.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_3_+Z_True.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_3_+Z_True.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_3_-X_False.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_3_-X_False.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_3_-X_False.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_3_-X_False.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_3_-X_True.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_3_-X_True.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_3_-X_True.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_3_-X_True.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_3_-Y_False.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_3_-Y_False.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_3_-Y_False.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_3_-Y_False.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_3_-Y_True.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_3_-Y_True.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_3_-Y_True.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_3_-Y_True.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_3_-Z_False.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_3_-Z_False.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_3_-Z_False.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_3_-Z_False.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_3_-Z_True.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_3_-Z_True.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepRUS_3_-Z_True.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepRUS_3_-Z_True.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepZeroVerify_False.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepZeroVerify_False.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepZeroVerify_False.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepZeroVerify_False.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepZeroVerify_True.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepZeroVerify_True.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.pauli_states.PrepZeroVerify_True.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.pauli_states.PrepZeroVerify_True.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.plus_h_state.PrepHStateFT.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.plus_h_state.PrepHStateFT.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.plus_h_state.PrepHStateFT.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.plus_h_state.PrepHStateFT.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.t_plus_state.PrepEncodeTDagPlusNonFT.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.t_plus_state.PrepEncodeTDagPlusNonFT.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.t_plus_state.PrepEncodeTDagPlusNonFT.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.t_plus_state.PrepEncodeTDagPlusNonFT.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.t_plus_state.PrepEncodeTPlusFT.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.t_plus_state.PrepEncodeTPlusFT.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.t_plus_state.PrepEncodeTPlusFT.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.t_plus_state.PrepEncodeTPlusFT.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.t_plus_state.PrepEncodeTPlusFTRUS_1.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.t_plus_state.PrepEncodeTPlusFTRUS_1.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.t_plus_state.PrepEncodeTPlusFTRUS_1.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.t_plus_state.PrepEncodeTPlusFTRUS_1.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.t_plus_state.PrepEncodeTPlusFTRUS_2.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.t_plus_state.PrepEncodeTPlusFTRUS_2.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.t_plus_state.PrepEncodeTPlusFTRUS_2.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.t_plus_state.PrepEncodeTPlusFTRUS_2.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.t_plus_state.PrepEncodeTPlusFTRUS_3.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.t_plus_state.PrepEncodeTPlusFTRUS_3.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.t_plus_state.PrepEncodeTPlusFTRUS_3.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.t_plus_state.PrepEncodeTPlusFTRUS_3.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.t_plus_state.PrepEncodeTPlusNonFT.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.t_plus_state.PrepEncodeTPlusNonFT.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.preps.t_plus_state.PrepEncodeTPlusNonFT.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.preps.t_plus_state.PrepEncodeTPlusNonFT.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.qec.qec_3parallel.ParallelFlagQECActiveCorrection.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.qec.qec_3parallel.ParallelFlagQECActiveCorrection.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.qec.qec_3parallel.ParallelFlagQECActiveCorrection.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.qec.qec_3parallel.ParallelFlagQECActiveCorrection.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.syn_extract.six_check_nonflagging.SixUnflaggedSyn.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.syn_extract.six_check_nonflagging.SixUnflaggedSyn.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.syn_extract.six_check_nonflagging.SixUnflaggedSyn.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.syn_extract.six_check_nonflagging.SixUnflaggedSyn.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.syn_extract.three_parallel_flagging.ThreeParallelFlaggingXZZ.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.syn_extract.three_parallel_flagging.ThreeParallelFlaggingXZZ.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.syn_extract.three_parallel_flagging.ThreeParallelFlaggingXZZ.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.syn_extract.three_parallel_flagging.ThreeParallelFlaggingXZZ.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.syn_extract.three_parallel_flagging.ThreeParallelFlaggingZXX.qasm b/python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.syn_extract.three_parallel_flagging.ThreeParallelFlaggingZXX.qasm similarity index 100% rename from python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.qeclib.steane.syn_extract.three_parallel_flagging.ThreeParallelFlaggingZXX.qasm rename to python/quantum-pecos/tests/pecos/regression/test_qasm/regression_qasm/pecos.slr.qeclib.steane.syn_extract.three_parallel_flagging.ThreeParallelFlaggingZXX.qasm diff --git a/python/quantum-pecos/tests/pecos/regression/test_qeclib/test_surface/test_new_surface_patch.py b/python/quantum-pecos/tests/pecos/regression/test_qeclib/test_surface/test_new_surface_patch.py index 2d2279fa2..0838091d6 100644 --- a/python/quantum-pecos/tests/pecos/regression/test_qeclib/test_surface/test_new_surface_patch.py +++ b/python/quantum-pecos/tests/pecos/regression/test_qeclib/test_surface/test_new_surface_patch.py @@ -1,6 +1,7 @@ """Tests for surface patch construction and rendering.""" -from pecos.qeclib.surface import ( +from pecos.slr import Main, SlrConverter +from pecos.slr.qeclib.surface import ( Lattice2DView, LatticeType, NonRotatedSurfacePatch, @@ -8,7 +9,6 @@ SurfacePatchBuilder, SurfacePatchOrientation, ) -from pecos.slr import Main, SlrConverter def test_default_rot_surface_patch() -> None: diff --git a/python/quantum-pecos/tests/pecos/unit/demo_parallel_optimization.py b/python/quantum-pecos/tests/pecos/unit/demo_parallel_optimization.py index 7fc3c14b1..7fb9be700 100644 --- a/python/quantum-pecos/tests/pecos/unit/demo_parallel_optimization.py +++ b/python/quantum-pecos/tests/pecos/unit/demo_parallel_optimization.py @@ -1,7 +1,7 @@ """Demonstration of ParallelOptimizer transformation with QASM output.""" -from pecos.qeclib import qubit as qb from pecos.slr import Block, Main, Parallel, QReg, SlrConverter +from pecos.slr.qeclib import qubit as qb def main() -> None: diff --git a/python/quantum-pecos/tests/pecos/unit/test_parallel_optimizer.py b/python/quantum-pecos/tests/pecos/unit/test_parallel_optimizer.py index 5de13208b..c440658f6 100644 --- a/python/quantum-pecos/tests/pecos/unit/test_parallel_optimizer.py +++ b/python/quantum-pecos/tests/pecos/unit/test_parallel_optimizer.py @@ -12,8 +12,8 @@ """Tests for the ParallelOptimizer transformation pass.""" import pytest -from pecos.qeclib import qubit as qb from pecos.slr import Block, CReg, If, Main, Parallel, QReg, Repeat +from pecos.slr.qeclib import qubit as qb from pecos.slr.transforms import ParallelOptimizer diff --git a/python/quantum-pecos/tests/pecos/unit/test_parallel_optimizer_example.py b/python/quantum-pecos/tests/pecos/unit/test_parallel_optimizer_example.py index 0cfdc2fcf..6cd8e27b2 100644 --- a/python/quantum-pecos/tests/pecos/unit/test_parallel_optimizer_example.py +++ b/python/quantum-pecos/tests/pecos/unit/test_parallel_optimizer_example.py @@ -11,8 +11,8 @@ """Example demonstrating the ParallelOptimizer transformation.""" -from pecos.qeclib import qubit as qb from pecos.slr import Block, CReg, Main, Parallel, QReg, SlrConverter +from pecos.slr.qeclib import qubit as qb from pecos.slr.transforms import ParallelOptimizer diff --git a/python/quantum-pecos/tests/pecos/unit/test_parallel_optimizer_verification.py b/python/quantum-pecos/tests/pecos/unit/test_parallel_optimizer_verification.py index f1e9e3ae3..32eb5f948 100644 --- a/python/quantum-pecos/tests/pecos/unit/test_parallel_optimizer_verification.py +++ b/python/quantum-pecos/tests/pecos/unit/test_parallel_optimizer_verification.py @@ -11,8 +11,8 @@ """Verification tests showing exact transformations performed by ParallelOptimizer.""" -from pecos.qeclib import qubit as qb from pecos.slr import Block, Main, Parallel, QReg +from pecos.slr.qeclib import qubit as qb from pecos.slr.transforms import ParallelOptimizer diff --git a/python/quantum-pecos/tests/pecos/unit/test_slr_converter_guppy.py b/python/quantum-pecos/tests/pecos/unit/test_slr_converter_guppy.py index 3e822f2f5..576701226 100644 --- a/python/quantum-pecos/tests/pecos/unit/test_slr_converter_guppy.py +++ b/python/quantum-pecos/tests/pecos/unit/test_slr_converter_guppy.py @@ -12,9 +12,9 @@ """Tests for SlrConverter Guppy functionality.""" -from pecos.qeclib import qubit as qb -from pecos.qeclib.steane.steane_class import Steane from pecos.slr import CReg, Main, Parallel, QReg, SlrConverter +from pecos.slr.qeclib import qubit as qb +from pecos.slr.qeclib.steane.steane_class import Steane def test_slr_converter_guppy_simple() -> None: diff --git a/python/quantum-pecos/tests/pecos/unit/test_slr_converter_parallel.py b/python/quantum-pecos/tests/pecos/unit/test_slr_converter_parallel.py index 806902d11..2712fcce1 100644 --- a/python/quantum-pecos/tests/pecos/unit/test_slr_converter_parallel.py +++ b/python/quantum-pecos/tests/pecos/unit/test_slr_converter_parallel.py @@ -11,8 +11,8 @@ """Tests for SlrConverter with ParallelOptimizer integration.""" -from pecos.qeclib import qubit as qb from pecos.slr import Block, CReg, Main, Parallel, QReg, SlrConverter +from pecos.slr.qeclib import qubit as qb def test_slr_converter_without_optimization() -> None: diff --git a/python/quantum-pecos/tests/slr-tests/guppy/demo_improvements.py b/python/quantum-pecos/tests/slr-tests/guppy/demo_improvements.py index 8dfdf2b47..9c50d392b 100644 --- a/python/quantum-pecos/tests/slr-tests/guppy/demo_improvements.py +++ b/python/quantum-pecos/tests/slr-tests/guppy/demo_improvements.py @@ -4,10 +4,10 @@ better code generation with precise, element-level analysis. """ -from pecos.qeclib import qubit from pecos.slr import CReg, If, Main, QReg from pecos.slr.gen_codes.guppy.data_flow import DataFlowAnalyzer from pecos.slr.gen_codes.guppy.ir_analyzer import IRAnalyzer +from pecos.slr.qeclib import qubit def demo_scenario(name: str, prog: Main, variables: dict) -> None: diff --git a/python/quantum-pecos/tests/slr-tests/guppy/test_allocation_optimization.py b/python/quantum-pecos/tests/slr-tests/guppy/test_allocation_optimization.py index a18f1c0a3..94a6f2b76 100644 --- a/python/quantum-pecos/tests/slr-tests/guppy/test_allocation_optimization.py +++ b/python/quantum-pecos/tests/slr-tests/guppy/test_allocation_optimization.py @@ -1,9 +1,9 @@ """Test allocation optimization in Guppy code generation.""" -from pecos.qeclib import qubit -from pecos.qeclib.qubit.measures import Measure from pecos.slr import CReg, For, If, Main, QReg from pecos.slr.gen_codes.guppy.ir_generator import IRGuppyGenerator +from pecos.slr.qeclib import qubit +from pecos.slr.qeclib.qubit.measures import Measure def test_short_lived_ancilla_optimization() -> None: diff --git a/python/quantum-pecos/tests/slr-tests/guppy/test_array_patterns.py b/python/quantum-pecos/tests/slr-tests/guppy/test_array_patterns.py index 79d13646e..128487e99 100644 --- a/python/quantum-pecos/tests/slr-tests/guppy/test_array_patterns.py +++ b/python/quantum-pecos/tests/slr-tests/guppy/test_array_patterns.py @@ -8,9 +8,9 @@ """ import pytest -from pecos.qeclib import qubit -from pecos.qeclib.qubit.measures import Measure from pecos.slr import Block, CReg, Main, Permute, QReg, SlrConverter +from pecos.slr.qeclib import qubit +from pecos.slr.qeclib.qubit.measures import Measure class TestArrayUnpacking: diff --git a/python/quantum-pecos/tests/slr-tests/guppy/test_complex_permutations.py b/python/quantum-pecos/tests/slr-tests/guppy/test_complex_permutations.py index c5c872c27..964a942dc 100644 --- a/python/quantum-pecos/tests/slr-tests/guppy/test_complex_permutations.py +++ b/python/quantum-pecos/tests/slr-tests/guppy/test_complex_permutations.py @@ -1,9 +1,9 @@ """Test complex permutation patterns in quantum circuits.""" -from pecos.qeclib import qubit -from pecos.qeclib.qubit.measures import Measure from pecos.slr import CReg, Main, Permute, QReg from pecos.slr.gen_codes.guppy.ir_generator import IRGuppyGenerator +from pecos.slr.qeclib import qubit +from pecos.slr.qeclib.qubit.measures import Measure def test_permute_identity() -> None: diff --git a/python/quantum-pecos/tests/slr-tests/guppy/test_conditional_refinement.py b/python/quantum-pecos/tests/slr-tests/guppy/test_conditional_refinement.py index eac34445d..a696c4536 100644 --- a/python/quantum-pecos/tests/slr-tests/guppy/test_conditional_refinement.py +++ b/python/quantum-pecos/tests/slr-tests/guppy/test_conditional_refinement.py @@ -4,9 +4,9 @@ conditionally accessed, rather than marking the entire array as conditional. """ -from pecos.qeclib import qubit from pecos.slr import CReg, If, Main, QReg from pecos.slr.gen_codes.guppy.ir_analyzer import IRAnalyzer +from pecos.slr.qeclib import qubit class TestConditionalElementTracking: diff --git a/python/quantum-pecos/tests/slr-tests/guppy/test_conditional_resources.py b/python/quantum-pecos/tests/slr-tests/guppy/test_conditional_resources.py index 33ab56076..a45ce73fc 100644 --- a/python/quantum-pecos/tests/slr-tests/guppy/test_conditional_resources.py +++ b/python/quantum-pecos/tests/slr-tests/guppy/test_conditional_resources.py @@ -1,9 +1,9 @@ """Tests for conditional resource consumption handling.""" import pytest -from pecos.qeclib import qubit -from pecos.qeclib.qubit.measures import Measure from pecos.slr import CReg, If, Main, QReg, SlrConverter +from pecos.slr.qeclib import qubit +from pecos.slr.qeclib.qubit.measures import Measure def test_conditional_measurement_without_else() -> None: diff --git a/python/quantum-pecos/tests/slr-tests/guppy/test_data_flow.py b/python/quantum-pecos/tests/slr-tests/guppy/test_data_flow.py index 1cc92a140..ed73be50f 100644 --- a/python/quantum-pecos/tests/slr-tests/guppy/test_data_flow.py +++ b/python/quantum-pecos/tests/slr-tests/guppy/test_data_flow.py @@ -1,8 +1,8 @@ """Test suite for data flow analysis.""" -from pecos.qeclib import qubit from pecos.slr import CReg, If, Main, QReg from pecos.slr.gen_codes.guppy.data_flow import DataFlowAnalyzer +from pecos.slr.qeclib import qubit class TestDataFlowBasics: diff --git a/python/quantum-pecos/tests/slr-tests/guppy/test_hugr_compilation.py b/python/quantum-pecos/tests/slr-tests/guppy/test_hugr_compilation.py index b3a9a1c38..e13904d67 100644 --- a/python/quantum-pecos/tests/slr-tests/guppy/test_hugr_compilation.py +++ b/python/quantum-pecos/tests/slr-tests/guppy/test_hugr_compilation.py @@ -5,9 +5,9 @@ """ import pytest -from pecos.qeclib import qubit -from pecos.qeclib.qubit.measures import Measure from pecos.slr import Block, CReg, If, Main, QReg, SlrConverter +from pecos.slr.qeclib import qubit +from pecos.slr.qeclib.qubit.measures import Measure @pytest.mark.optional_dependency diff --git a/python/quantum-pecos/tests/slr-tests/guppy/test_hugr_error_messages.py b/python/quantum-pecos/tests/slr-tests/guppy/test_hugr_error_messages.py index 248911ab3..1e371a368 100644 --- a/python/quantum-pecos/tests/slr-tests/guppy/test_hugr_error_messages.py +++ b/python/quantum-pecos/tests/slr-tests/guppy/test_hugr_error_messages.py @@ -1,7 +1,7 @@ """Test improved HUGR error messages.""" -from pecos.qeclib.qubit.measures import Measure from pecos.slr import CReg, Main, QReg +from pecos.slr.qeclib.qubit.measures import Measure def test_place_not_used_error() -> None: diff --git a/python/quantum-pecos/tests/slr-tests/guppy/test_ir_basic.py b/python/quantum-pecos/tests/slr-tests/guppy/test_ir_basic.py index 3239d4de3..2913fbaa4 100644 --- a/python/quantum-pecos/tests/slr-tests/guppy/test_ir_basic.py +++ b/python/quantum-pecos/tests/slr-tests/guppy/test_ir_basic.py @@ -1,9 +1,9 @@ """Basic tests for IR generator functionality.""" -from pecos.qeclib import qubit -from pecos.qeclib.qubit.measures import Measure from pecos.slr import CReg, If, Main, QReg from pecos.slr.gen_codes.guppy.ir_generator import IRGuppyGenerator +from pecos.slr.qeclib import qubit +from pecos.slr.qeclib.qubit.measures import Measure def test_ir_generates_valid_guppy() -> None: diff --git a/python/quantum-pecos/tests/slr-tests/guppy/test_ir_for_loops.py b/python/quantum-pecos/tests/slr-tests/guppy/test_ir_for_loops.py index 3985d3098..7a8931561 100644 --- a/python/quantum-pecos/tests/slr-tests/guppy/test_ir_for_loops.py +++ b/python/quantum-pecos/tests/slr-tests/guppy/test_ir_for_loops.py @@ -1,11 +1,11 @@ """Test For loop implementation in IR generator.""" import pytest -from pecos.qeclib import qubit -from pecos.qeclib.qubit.measures import Measure from pecos.slr import CReg, For, Main, QReg from pecos.slr.gen_codes.guppy.ir_generator import IRGuppyGenerator from pecos.slr.misc import Comment +from pecos.slr.qeclib import qubit +from pecos.slr.qeclib.qubit.measures import Measure def test_for_loop_range_basic() -> None: diff --git a/python/quantum-pecos/tests/slr-tests/guppy/test_ir_generator.py b/python/quantum-pecos/tests/slr-tests/guppy/test_ir_generator.py index 23c33d806..c4efe700e 100644 --- a/python/quantum-pecos/tests/slr-tests/guppy/test_ir_generator.py +++ b/python/quantum-pecos/tests/slr-tests/guppy/test_ir_generator.py @@ -1,9 +1,9 @@ """Test the IR-based Guppy generator.""" -from pecos.qeclib import qubit -from pecos.qeclib.qubit.measures import Measure from pecos.slr import CReg, If, Main, QReg from pecos.slr.gen_codes.guppy.ir_generator import IRGuppyGenerator +from pecos.slr.qeclib import qubit +from pecos.slr.qeclib.qubit.measures import Measure def test_ir_simple_measurement() -> None: diff --git a/python/quantum-pecos/tests/slr-tests/guppy/test_ir_hugr_compatibility.py b/python/quantum-pecos/tests/slr-tests/guppy/test_ir_hugr_compatibility.py index 66f746f06..046a35aea 100644 --- a/python/quantum-pecos/tests/slr-tests/guppy/test_ir_hugr_compatibility.py +++ b/python/quantum-pecos/tests/slr-tests/guppy/test_ir_hugr_compatibility.py @@ -1,9 +1,9 @@ """Test IR generator with HUGR compilation scenarios.""" -from pecos.qeclib import qubit -from pecos.qeclib.qubit.measures import Measure from pecos.slr import CReg, If, Main, QReg from pecos.slr.gen_codes.guppy.ir_generator import IRGuppyGenerator +from pecos.slr.qeclib import qubit +from pecos.slr.qeclib.qubit.measures import Measure def test_ir_handles_array_measurement_patterns() -> None: diff --git a/python/quantum-pecos/tests/slr-tests/guppy/test_ir_permute.py b/python/quantum-pecos/tests/slr-tests/guppy/test_ir_permute.py index 8b8f5a5dc..c60627cce 100644 --- a/python/quantum-pecos/tests/slr-tests/guppy/test_ir_permute.py +++ b/python/quantum-pecos/tests/slr-tests/guppy/test_ir_permute.py @@ -1,9 +1,9 @@ """Test Permute operation in IR generator.""" -from pecos.qeclib import qubit -from pecos.qeclib.qubit.measures import Measure from pecos.slr import CReg, Main, Permute, QReg from pecos.slr.gen_codes.guppy.ir_generator import IRGuppyGenerator +from pecos.slr.qeclib import qubit +from pecos.slr.qeclib.qubit.measures import Measure def test_ir_simple_permute() -> None: diff --git a/python/quantum-pecos/tests/slr-tests/guppy/test_ir_scope_management.py b/python/quantum-pecos/tests/slr-tests/guppy/test_ir_scope_management.py index b8291b6d1..670ac3dcc 100644 --- a/python/quantum-pecos/tests/slr-tests/guppy/test_ir_scope_management.py +++ b/python/quantum-pecos/tests/slr-tests/guppy/test_ir_scope_management.py @@ -1,8 +1,8 @@ """Test scope management in IR generator.""" -from pecos.qeclib.qubit.measures import Measure from pecos.slr import CReg, If, Main, QReg from pecos.slr.gen_codes.guppy.ir_generator import IRGuppyGenerator +from pecos.slr.qeclib.qubit.measures import Measure def test_conditional_resource_balancing() -> None: diff --git a/python/quantum-pecos/tests/slr-tests/guppy/test_ir_while_loops.py b/python/quantum-pecos/tests/slr-tests/guppy/test_ir_while_loops.py index ce974a1a1..606fe9edc 100644 --- a/python/quantum-pecos/tests/slr-tests/guppy/test_ir_while_loops.py +++ b/python/quantum-pecos/tests/slr-tests/guppy/test_ir_while_loops.py @@ -1,11 +1,11 @@ """Test While loop support in IR generator.""" import pytest -from pecos.qeclib import qubit -from pecos.qeclib.qubit.measures import Measure from pecos.slr import CReg, For, Main, QReg, While from pecos.slr.gen_codes.guppy.ir_generator import IRGuppyGenerator from pecos.slr.misc import Comment +from pecos.slr.qeclib import qubit +from pecos.slr.qeclib.qubit.measures import Measure def test_ir_while_loop_basic() -> None: diff --git a/python/quantum-pecos/tests/slr-tests/guppy/test_linearity_patterns.py b/python/quantum-pecos/tests/slr-tests/guppy/test_linearity_patterns.py index 48df6551a..3b5ec4607 100644 --- a/python/quantum-pecos/tests/slr-tests/guppy/test_linearity_patterns.py +++ b/python/quantum-pecos/tests/slr-tests/guppy/test_linearity_patterns.py @@ -8,9 +8,9 @@ """ import pytest -from pecos.qeclib import qubit -from pecos.qeclib.qubit.measures import Measure from pecos.slr import Block, CReg, If, Main, QReg, SlrConverter +from pecos.slr.qeclib import qubit +from pecos.slr.qeclib.qubit.measures import Measure class TestLinearityPatterns: diff --git a/python/quantum-pecos/tests/slr-tests/guppy/test_loop_generation.py b/python/quantum-pecos/tests/slr-tests/guppy/test_loop_generation.py index 1966b76ae..aff10b82f 100644 --- a/python/quantum-pecos/tests/slr-tests/guppy/test_loop_generation.py +++ b/python/quantum-pecos/tests/slr-tests/guppy/test_loop_generation.py @@ -1,8 +1,8 @@ """Test loop generation for register-wide operations.""" -from pecos.qeclib import qubit -from pecos.qeclib.qubit.measures import Measure from pecos.slr import Block, CReg, Main, QReg, SlrConverter +from pecos.slr.qeclib import qubit +from pecos.slr.qeclib.qubit.measures import Measure def test_consecutive_gate_applications() -> None: diff --git a/python/quantum-pecos/tests/slr-tests/guppy/test_measurement_optimization.py b/python/quantum-pecos/tests/slr-tests/guppy/test_measurement_optimization.py index 1ebac4656..e04ee760e 100644 --- a/python/quantum-pecos/tests/slr-tests/guppy/test_measurement_optimization.py +++ b/python/quantum-pecos/tests/slr-tests/guppy/test_measurement_optimization.py @@ -6,9 +6,9 @@ - Handles mixed measurement patterns efficiently """ -from pecos.qeclib import qubit -from pecos.qeclib.qubit.measures import Measure from pecos.slr import Block, CReg, If, Main, QReg, SlrConverter +from pecos.slr.qeclib import qubit +from pecos.slr.qeclib.qubit.measures import Measure class TestMeasurementOptimization: diff --git a/python/quantum-pecos/tests/slr-tests/guppy/test_multi_qubit_measurements.py b/python/quantum-pecos/tests/slr-tests/guppy/test_multi_qubit_measurements.py index ed57429ae..08e2d1c74 100644 --- a/python/quantum-pecos/tests/slr-tests/guppy/test_multi_qubit_measurements.py +++ b/python/quantum-pecos/tests/slr-tests/guppy/test_multi_qubit_measurements.py @@ -1,7 +1,7 @@ """Test multi-qubit measurement support in Guppy IR builder.""" -from pecos.qeclib import qubit from pecos.slr import Block, CReg, QReg +from pecos.slr.qeclib import qubit from pecos.slr.slr_converter import SlrConverter diff --git a/python/quantum-pecos/tests/slr-tests/guppy/test_partial_array_returns.py b/python/quantum-pecos/tests/slr-tests/guppy/test_partial_array_returns.py index 995eabe12..48ca7dbb6 100644 --- a/python/quantum-pecos/tests/slr-tests/guppy/test_partial_array_returns.py +++ b/python/quantum-pecos/tests/slr-tests/guppy/test_partial_array_returns.py @@ -1,8 +1,8 @@ """Tests for functions returning partial arrays.""" -from pecos.qeclib import qubit -from pecos.qeclib.qubit.measures import Measure from pecos.slr import Block, CReg, Main, QReg, SlrConverter +from pecos.slr.qeclib import qubit +from pecos.slr.qeclib.qubit.measures import Measure def test_function_returns_unconsumed_qubits() -> None: diff --git a/python/quantum-pecos/tests/slr-tests/guppy/test_partial_consumption.py b/python/quantum-pecos/tests/slr-tests/guppy/test_partial_consumption.py index 9c6ca7506..cae9c62ae 100644 --- a/python/quantum-pecos/tests/slr-tests/guppy/test_partial_consumption.py +++ b/python/quantum-pecos/tests/slr-tests/guppy/test_partial_consumption.py @@ -7,9 +7,9 @@ """ import pytest -from pecos.qeclib import qubit -from pecos.qeclib.qubit.measures import Measure from pecos.slr import Block, CReg, Main, QReg, SlrConverter +from pecos.slr.qeclib import qubit +from pecos.slr.qeclib.qubit.measures import Measure class TestPartialConsumption: diff --git a/python/quantum-pecos/tests/slr-tests/guppy/test_register_wide_ops.py b/python/quantum-pecos/tests/slr-tests/guppy/test_register_wide_ops.py index fbf551a1d..20da744f6 100644 --- a/python/quantum-pecos/tests/slr-tests/guppy/test_register_wide_ops.py +++ b/python/quantum-pecos/tests/slr-tests/guppy/test_register_wide_ops.py @@ -1,8 +1,8 @@ """Test register-wide operations that should generate loops.""" -from pecos.qeclib import qubit -from pecos.qeclib.qubit.measures import Measure from pecos.slr import CReg, Main, QReg, SlrConverter +from pecos.slr.qeclib import qubit +from pecos.slr.qeclib.qubit.measures import Measure def test_hadamard_on_register() -> None: diff --git a/python/quantum-pecos/tests/slr-tests/guppy/test_simple_slr_to_guppy.py b/python/quantum-pecos/tests/slr-tests/guppy/test_simple_slr_to_guppy.py index 21e8e826c..588694854 100644 --- a/python/quantum-pecos/tests/slr-tests/guppy/test_simple_slr_to_guppy.py +++ b/python/quantum-pecos/tests/slr-tests/guppy/test_simple_slr_to_guppy.py @@ -5,10 +5,10 @@ of expected translations and regression tests. """ -from pecos.qeclib import qubit as qb -from pecos.qeclib.qubit.measures import Measure -from pecos.qeclib.qubit.preps import Prep from pecos.slr import Block, CReg, Main, QReg, SlrConverter +from pecos.slr.qeclib import qubit as qb +from pecos.slr.qeclib.qubit.measures import Measure +from pecos.slr.qeclib.qubit.preps import Prep def test_simple_bell_state() -> None: diff --git a/python/quantum-pecos/tests/slr-tests/guppy/test_steane_integration.py b/python/quantum-pecos/tests/slr-tests/guppy/test_steane_integration.py index 950fef27a..b1ca5df16 100644 --- a/python/quantum-pecos/tests/slr-tests/guppy/test_steane_integration.py +++ b/python/quantum-pecos/tests/slr-tests/guppy/test_steane_integration.py @@ -5,8 +5,8 @@ error correction code. """ -from pecos.qeclib.steane.steane_class import Steane from pecos.slr import Main, SlrConverter +from pecos.slr.qeclib.steane.steane_class import Steane def test_steane_guppy_generation() -> None: diff --git a/python/quantum-pecos/tests/slr-tests/guppy/test_unified_resource_planner.py b/python/quantum-pecos/tests/slr-tests/guppy/test_unified_resource_planner.py index 0661bf8dd..97a68c8d3 100644 --- a/python/quantum-pecos/tests/slr-tests/guppy/test_unified_resource_planner.py +++ b/python/quantum-pecos/tests/slr-tests/guppy/test_unified_resource_planner.py @@ -4,13 +4,13 @@ and data flow analysis into a coherent resource management plan. """ -from pecos.qeclib import qubit from pecos.slr import CReg, For, If, Main, QReg from pecos.slr.gen_codes.guppy.unified_resource_planner import ( DecisionPriority, ResourceStrategy, UnifiedResourcePlanner, ) +from pecos.slr.qeclib import qubit class TestBasicUnifiedPlanning: diff --git a/python/quantum-pecos/tests/slr-tests/pecos/regression/random_cases/test_slr_phys.py b/python/quantum-pecos/tests/slr-tests/pecos/regression/random_cases/test_slr_phys.py index 3eeb62c04..9b6d0f9f5 100644 --- a/python/quantum-pecos/tests/slr-tests/pecos/regression/random_cases/test_slr_phys.py +++ b/python/quantum-pecos/tests/slr-tests/pecos/regression/random_cases/test_slr_phys.py @@ -3,8 +3,6 @@ import re import pytest -from pecos.qeclib import qubit as p -from pecos.qeclib.steane.steane_class import Steane from pecos.slr import ( Barrier, Block, @@ -17,6 +15,8 @@ Repeat, SlrConverter, ) +from pecos.slr.qeclib import qubit as p +from pecos.slr.qeclib.steane.steane_class import Steane # TODO: Remove reference to hqslib1.inc... better yet, don't have tests on qasm diff --git a/python/quantum-pecos/tests/slr-tests/pecos/unit/slr/conftest.py b/python/quantum-pecos/tests/slr-tests/pecos/unit/slr/conftest.py index 45e253458..480179312 100644 --- a/python/quantum-pecos/tests/slr-tests/pecos/unit/slr/conftest.py +++ b/python/quantum-pecos/tests/slr-tests/pecos/unit/slr/conftest.py @@ -1,8 +1,8 @@ """Pytest fixtures for SLR tests.""" import pytest -from pecos.qeclib import qubit from pecos.slr import CReg, Main, Permute, QReg +from pecos.slr.qeclib import qubit @pytest.fixture diff --git a/python/quantum-pecos/tests/slr-tests/pecos/unit/slr/test_complex_permutation.py b/python/quantum-pecos/tests/slr-tests/pecos/unit/slr/test_complex_permutation.py index 3bb85a9b3..8ec7c57c1 100644 --- a/python/quantum-pecos/tests/slr-tests/pecos/unit/slr/test_complex_permutation.py +++ b/python/quantum-pecos/tests/slr-tests/pecos/unit/slr/test_complex_permutation.py @@ -3,8 +3,8 @@ import re import pytest -from pecos.qeclib import qubit from pecos.slr import CReg, If, Main, Permute, QReg, SlrConverter +from pecos.slr.qeclib import qubit # QASM Tests diff --git a/python/quantum-pecos/tests/slr-tests/pecos/unit/slr/test_conversion_with_qasm.py b/python/quantum-pecos/tests/slr-tests/pecos/unit/slr/test_conversion_with_qasm.py index f7241fd93..aaa0fafb2 100644 --- a/python/quantum-pecos/tests/slr-tests/pecos/unit/slr/test_conversion_with_qasm.py +++ b/python/quantum-pecos/tests/slr-tests/pecos/unit/slr/test_conversion_with_qasm.py @@ -9,9 +9,9 @@ ) import pytest -from pecos.qeclib import qubit from pecos.slr import CReg, Main, Parallel, QReg, Repeat, SlrConverter from pecos.slr.gen_codes.gen_quantum_circuit import QuantumCircuitGenerator +from pecos.slr.qeclib import qubit # Check if stim is available for additional testing try: diff --git a/python/quantum-pecos/tests/slr-tests/pecos/unit/slr/test_guppy_generation.py b/python/quantum-pecos/tests/slr-tests/pecos/unit/slr/test_guppy_generation.py index a1ed4e27c..af6183daa 100644 --- a/python/quantum-pecos/tests/slr-tests/pecos/unit/slr/test_guppy_generation.py +++ b/python/quantum-pecos/tests/slr-tests/pecos/unit/slr/test_guppy_generation.py @@ -1,7 +1,7 @@ """Tests for Guppy code generation from SLR programs.""" -from pecos.qeclib import qubit as qb from pecos.slr import CReg, If, Main, QReg, Repeat, SlrConverter +from pecos.slr.qeclib import qubit as qb def test_simple_circuit() -> None: @@ -65,7 +65,7 @@ def test_repeat_loop() -> None: def test_steane_snippet() -> None: """Test a simple Steane code snippet.""" - from pecos.qeclib.steane.steane_class import Steane + from pecos.slr.qeclib.steane.steane_class import Steane prog = Main( # Create two logical qubits diff --git a/python/quantum-pecos/tests/slr-tests/pecos/unit/slr/test_guppy_generation_comprehensive.py b/python/quantum-pecos/tests/slr-tests/pecos/unit/slr/test_guppy_generation_comprehensive.py index 9443cdcb9..96f1a4a55 100644 --- a/python/quantum-pecos/tests/slr-tests/pecos/unit/slr/test_guppy_generation_comprehensive.py +++ b/python/quantum-pecos/tests/slr-tests/pecos/unit/slr/test_guppy_generation_comprehensive.py @@ -4,8 +4,8 @@ to ensure the Guppy generator produces correct output for diverse scenarios. """ -from pecos.qeclib import qubit as qb from pecos.slr import CReg, If, Main, Permute, QReg, Repeat, SlrConverter +from pecos.slr.qeclib import qubit as qb def test_quantum_teleportation() -> None: diff --git a/python/quantum-pecos/tests/slr-tests/pecos/unit/slr/test_measurement_unrolling.py b/python/quantum-pecos/tests/slr-tests/pecos/unit/slr/test_measurement_unrolling.py index 7b14ae921..1a489f281 100644 --- a/python/quantum-pecos/tests/slr-tests/pecos/unit/slr/test_measurement_unrolling.py +++ b/python/quantum-pecos/tests/slr-tests/pecos/unit/slr/test_measurement_unrolling.py @@ -1,8 +1,8 @@ """Tests for measurement unrolling with permutations in both QASM and QIR generation.""" import pytest -from pecos.qeclib import qubit from pecos.slr import CReg, Main, Permute, QReg, SlrConverter +from pecos.slr.qeclib import qubit def create_measurement_unrolling_program() -> tuple: diff --git a/python/quantum-pecos/tests/slr-tests/pecos/unit/slr/test_quantum_circuit_conversion.py b/python/quantum-pecos/tests/slr-tests/pecos/unit/slr/test_quantum_circuit_conversion.py index f8210d19b..a42ef63dc 100644 --- a/python/quantum-pecos/tests/slr-tests/pecos/unit/slr/test_quantum_circuit_conversion.py +++ b/python/quantum-pecos/tests/slr-tests/pecos/unit/slr/test_quantum_circuit_conversion.py @@ -10,9 +10,9 @@ import pytest from pecos.circuits.quantum_circuit import QuantumCircuit -from pecos.qeclib import qubit from pecos.slr import CReg, For, Main, Parallel, QReg, Repeat, SlrConverter from pecos.slr.gen_codes.gen_quantum_circuit import QuantumCircuitGenerator +from pecos.slr.qeclib import qubit class TestQuantumCircuitToSLR: diff --git a/python/quantum-pecos/tests/slr-tests/pecos/unit/slr/test_quantum_permutation.py b/python/quantum-pecos/tests/slr-tests/pecos/unit/slr/test_quantum_permutation.py index 828a1839a..b179c1f2d 100644 --- a/python/quantum-pecos/tests/slr-tests/pecos/unit/slr/test_quantum_permutation.py +++ b/python/quantum-pecos/tests/slr-tests/pecos/unit/slr/test_quantum_permutation.py @@ -3,8 +3,8 @@ import re import pytest -from pecos.qeclib import qubit from pecos.slr import CReg, Main, Permute, QReg, SlrConverter +from pecos.slr.qeclib import qubit # QASM Tests diff --git a/python/quantum-pecos/tests/slr-tests/pecos/unit/slr/test_register_permutation.py b/python/quantum-pecos/tests/slr-tests/pecos/unit/slr/test_register_permutation.py index a61276237..c9731b36e 100644 --- a/python/quantum-pecos/tests/slr-tests/pecos/unit/slr/test_register_permutation.py +++ b/python/quantum-pecos/tests/slr-tests/pecos/unit/slr/test_register_permutation.py @@ -3,8 +3,8 @@ import re import pytest -from pecos.qeclib import qubit from pecos.slr import CReg, Main, Permute, QReg, SlrConverter +from pecos.slr.qeclib import qubit # Test fixtures diff --git a/python/quantum-pecos/tests/slr-tests/pecos/unit/slr/test_stim_conversion.py b/python/quantum-pecos/tests/slr-tests/pecos/unit/slr/test_stim_conversion.py index 84e6df653..91570cd5c 100644 --- a/python/quantum-pecos/tests/slr-tests/pecos/unit/slr/test_stim_conversion.py +++ b/python/quantum-pecos/tests/slr-tests/pecos/unit/slr/test_stim_conversion.py @@ -1,8 +1,8 @@ """Tests for Stim circuit to/from SLR conversion.""" import pytest -from pecos.qeclib import qubit from pecos.slr import CReg, Main, Parallel, QReg, Repeat, SlrConverter +from pecos.slr.qeclib import qubit # Check if stim is available try: diff --git a/python/quantum-pecos/tests/slr-tests/test_partial.py b/python/quantum-pecos/tests/slr-tests/test_partial.py index 9eea0c0e9..96493636f 100644 --- a/python/quantum-pecos/tests/slr-tests/test_partial.py +++ b/python/quantum-pecos/tests/slr-tests/test_partial.py @@ -1,8 +1,8 @@ """Test partial array consumption in SLR.""" -from pecos.qeclib import qubit -from pecos.qeclib.qubit.measures import Measure from pecos.slr import Block, CReg, Main, QReg, SlrConverter +from pecos.slr.qeclib import qubit +from pecos.slr.qeclib.qubit.measures import Measure class MeasureAncillas(Block): diff --git a/python/quantum-pecos/tests/slr/pecos/unit/slr/conftest.py b/python/quantum-pecos/tests/slr/pecos/unit/slr/conftest.py index 45e253458..480179312 100644 --- a/python/quantum-pecos/tests/slr/pecos/unit/slr/conftest.py +++ b/python/quantum-pecos/tests/slr/pecos/unit/slr/conftest.py @@ -1,8 +1,8 @@ """Pytest fixtures for SLR tests.""" import pytest -from pecos.qeclib import qubit from pecos.slr import CReg, Main, Permute, QReg +from pecos.slr.qeclib import qubit @pytest.fixture diff --git a/python/quantum-pecos/tests/slr/pecos/unit/slr/test_complex_permutation.py b/python/quantum-pecos/tests/slr/pecos/unit/slr/test_complex_permutation.py index d43ef739b..b27d0e964 100644 --- a/python/quantum-pecos/tests/slr/pecos/unit/slr/test_complex_permutation.py +++ b/python/quantum-pecos/tests/slr/pecos/unit/slr/test_complex_permutation.py @@ -3,8 +3,8 @@ import re import pytest -from pecos.qeclib import qubit from pecos.slr import CReg, If, Main, Permute, QReg, SlrConverter +from pecos.slr.qeclib import qubit # QASM Tests diff --git a/python/quantum-pecos/tests/slr/pecos/unit/slr/test_measurement_unrolling.py b/python/quantum-pecos/tests/slr/pecos/unit/slr/test_measurement_unrolling.py index 7fc2ce502..5ccab3e35 100644 --- a/python/quantum-pecos/tests/slr/pecos/unit/slr/test_measurement_unrolling.py +++ b/python/quantum-pecos/tests/slr/pecos/unit/slr/test_measurement_unrolling.py @@ -1,8 +1,8 @@ """Tests for measurement unrolling with permutations in both QASM and QIR generation.""" import pytest -from pecos.qeclib import qubit from pecos.slr import CReg, Main, Permute, QReg, SlrConverter +from pecos.slr.qeclib import qubit def create_measurement_unrolling_program() -> tuple: diff --git a/python/quantum-pecos/tests/slr/pecos/unit/slr/test_quantum_permutation.py b/python/quantum-pecos/tests/slr/pecos/unit/slr/test_quantum_permutation.py index 6bb8f3f20..207bfe37d 100644 --- a/python/quantum-pecos/tests/slr/pecos/unit/slr/test_quantum_permutation.py +++ b/python/quantum-pecos/tests/slr/pecos/unit/slr/test_quantum_permutation.py @@ -3,8 +3,8 @@ import re import pytest -from pecos.qeclib import qubit from pecos.slr import CReg, Main, Permute, QReg, SlrConverter +from pecos.slr.qeclib import qubit # QASM Tests diff --git a/python/quantum-pecos/tests/slr/pecos/unit/slr/test_register_permutation.py b/python/quantum-pecos/tests/slr/pecos/unit/slr/test_register_permutation.py index a61276237..c9731b36e 100644 --- a/python/quantum-pecos/tests/slr/pecos/unit/slr/test_register_permutation.py +++ b/python/quantum-pecos/tests/slr/pecos/unit/slr/test_register_permutation.py @@ -3,8 +3,8 @@ import re import pytest -from pecos.qeclib import qubit from pecos.slr import CReg, Main, Permute, QReg, SlrConverter +from pecos.slr.qeclib import qubit # Test fixtures