Architecture Overview¶
This document provides an overview of LeeQ's architecture and design principles.
System Architecture¶
LeeQ follows a modular, layered architecture designed for flexibility and extensibility:
┌─────────────────────────────────────────┐
│ User Interface Layer │
│ (Experiments, Calibrations, API) │
└─────────────────────────────────────────┘
│
┌─────────────────────────────────────────┐
│ Core Abstraction Layer │
│ (Elements, Primitives, Engine) │
└─────────────────────────────────────────┘
│
┌─────────────────────────────────────────┐
│ Compiler & Execution Layer │
│ (Pulse Compilation, Sequencing) │
└─────────────────────────────────────────┘
│
┌─────────────────────────────────────────┐
│ Hardware Interface Layer │
│ (QubiC, Simulation, Virtual Device) │
└─────────────────────────────────────────┘
Core Components¶
1. Base Classes (leeq.core.base)¶
All LeeQ objects inherit from LeeQObject, which provides:
- Automatic persistence via leeq.chronicle (integrated module)
- Parameter tracking and versioning
- Serialization capabilities
class LeeQObject(LoggableObject):
"""Base class for all LeeQ components."""
pass
2. Quantum Elements (leeq.core.elements)¶
Represents quantum systems: - Qubit: Basic qubit implementation - Transmon: Transmon-specific features - Resonator: Readout resonators - QuditTransmon: Multi-level transmon
Elements maintain: - Calibration parameters - Gate definitions - Measurement configurations
3. Primitives (leeq.core.primitives)¶
Low-level operations: - Drive primitives: Gaussian, DRAG pulses - Measurement primitives: Dispersive readout - Gate primitives: Single and two-qubit gates - Collections: Primitive sequences
4. Execution Engine (leeq.core.engine)¶
Manages experiment execution: - Sweeper: Parameter sweep management - MeasurementManager: Data collection - BatchManager: Experiment batching - ResultProcessor: Data processing
5. Compiler (leeq.compiler)¶
Translates high-level operations to hardware instructions: - PulseCompiler: Pulse shape generation - SequenceCompiler: Instruction sequencing - CalibrationManager: Parameter optimization
Design Patterns¶
Dependency Injection¶
class Experiment:
def __init__(self, setup, compiler=None):
self.setup = setup
self.compiler = compiler or setup.default_compiler
Factory Pattern¶
def create_experiment(experiment_type, **kwargs):
"""Factory for creating experiments."""
if experiment_type == "rabi":
return RabiExperiment(**kwargs)
elif experiment_type == "ramsey":
return RamseyExperiment(**kwargs)
Strategy Pattern¶
Different backends implement the same interface:
class Backend(ABC):
@abstractmethod
def execute(self, circuit):
pass
class QubiCBackend(Backend):
def execute(self, circuit):
# QubiC-specific implementation
pass
class SimulationBackend(Backend):
def execute(self, circuit):
# Simulation implementation
pass
Data Flow¶
User Code
│
├──> Experiment Definition
│ │
│ ├──> Parameter Sweeps
│ │
│ └──> Pulse Sequences
│
├──> Compilation
│ │
│ ├──> Gate Decomposition
│ │
│ └──> Pulse Generation
│
├──> Execution
│ │
│ ├──> Hardware Interface
│ │
│ └──> Data Collection
│
└──> Analysis
│
├──> Fitting
│
└──> Visualization
Module Organization¶
Core Modules¶
leeq/
├── core/
│ ├── base.py # Base classes
│ ├── context.py # Execution context
│ ├── elements/ # Quantum elements
│ ├── engine/ # Execution engine
│ └── primitives/ # Low-level operations
Experiment Modules¶
experiments/
├── builtin/ # Standard experiments
│ ├── basic/ # Basic calibrations
│ ├── tomography/ # State/process tomography
│ └── benchmarking/ # RB, XEB, etc.
├── sweeper.py # Parameter sweeping
└── base.py # Base experiment class
Theory Modules¶
theory/
├── simulation/ # Simulation backends
│ ├── numpy/ # NumPy-based
│ └── qutip/ # QuTiP integration
├── cliffords/ # Clifford operations
└── fits/ # Fitting routines
Extension Points¶
Adding New Experiments¶
- Inherit from
BaseExperiment - Implement required methods
- Register with experiment factory
class CustomExperiment(BaseExperiment):
def build_sequence(self):
# Define pulse sequence
pass
def analyze_results(self, data):
# Process measurement data
pass
Adding Hardware Backends¶
- Implement
Backendinterface - Handle compilation specifics
- Provide execution method
class NewBackend(Backend):
def compile(self, circuit):
# Backend-specific compilation
pass
def execute(self, compiled_circuit):
# Execute on hardware
pass
Performance Considerations¶
Caching¶
- Calibration parameters cached
- Compiled sequences cached
- Fitting results cached
Parallelization¶
- Parallel sweep execution
- Batch compilation
- Concurrent data processing
Memory Management¶
- Lazy loading of large datasets
- Streaming data processing
- Automatic cleanup of temporary data
Configuration¶
Environment Variables¶
LEEQ_BACKEND=qubic # Default backend
LEEQ_CACHE_DIR=/tmp/leeq # Cache directory
LEEQ_LOG_LEVEL=INFO # Logging level
Configuration Files¶
# leeq_config.yaml
backend:
type: qubic
host: localhost
port: 8080
compiler:
optimization_level: 2
cache_compiled: true
execution:
batch_size: 1000
timeout: 60
Error Handling¶
Exception Hierarchy¶
class LeeQError(Exception):
"""Base exception for LeeQ."""
pass
class CalibrationError(LeeQError):
"""Calibration-related errors."""
pass
class CompilationError(LeeQError):
"""Compilation errors."""
pass
class ExecutionError(LeeQError):
"""Execution errors."""
pass
Error Recovery¶
- Automatic retry on transient failures
- Fallback to simulation on hardware errors
- Graceful degradation of functionality
Future Directions¶
Planned Features¶
- Distributed Execution: Multi-node experiment execution
- Real-time Calibration: Adaptive calibration during experiments
- ML Integration: Machine learning for calibration optimization
- Cloud Support: Cloud-based backends and storage
API Stability¶
- Core API stable (v1.0+)
- Experimental features marked clearly
- Deprecation warnings for breaking changes
- Migration guides for major updates