Project Overview
Quantum Circuit Optimization is a comprehensive toolkit that bridges quantum computing and large language models (LLMs). It provides tools for generating quantum circuit datasets using Cirq and optimizing them via AI providers such as OpenRouter and Google Gemini.
The project follows an in-context learning approach โ providing the LLM with example input/output circuit pairs so it learns the optimization pattern, then applying that learned pattern to new circuits.
Features
๐ฌ Dataset Generation
Create random quantum circuits using Cirq with configurable parameters โ qubit count, gate range, noise levels.
๐ Noise Simulation
Simulate circuits with depolarizing, bit-flip, or phase-flip noise models. Also supports noiseless statevector simulation.
๐ค AI Optimization
Use LLMs via OpenRouter for circuit optimization through in-context learning with custom examples.
โจ๏ธ Unified CLI
Single command-line interface for both dataset generation and circuit optimization with multiple provider support.
Project Structure
quantum-circuit-optimization/ โโโ src/ โ โโโ data_generation/ # Quantum circuit dataset generation โ โ โโโ qc/ # Core quantum computing modules โ โ โ โโโ circuit_generation.py # Circuit creation & representation โ โ โ โโโ simulation.py # Noise & statevector simulation โ โ โ โโโ optimization.py # Cirq built-in optimization โ โ โโโ scripts/ โ โ โโโ generate_dataset.py # CLI dataset generator โ โ โโโ tests/ โ โ โโโ test_qc.py # pytest + hypothesis tests โ โโโ model_training/ # AI-powered circuit optimization โ โโโ config.py # Provider configuration โ โโโ openrouter_optimizer.py # OpenRouter API integration โ โโโ utils.py # Validation & parsing utilities โ โโโ cli/ โ โโโ predict.py # Unified CLI for optimization โโโ requirements.txt # Pinned dependencies โโโ pytest.ini # Test configuration โโโ LICENSE # MIT-0 License โโโ README.md
Installation
Prerequisites
- Python 3.10 or later
- Virtual environment support (venv, uv, conda)
- OpenRouter API key (for LLM optimization)
Clone & Setup
# Clone the repository
git clone https://github.com/waifuai/quantum-circuit-optimization.git
cd quantum-circuit-optimization
# Using uv (recommended)
python -m venv .venv
source .venv/bin/activate # Linux/macOS
# .venv\Scripts\activate # Windows
pip install uv
uv pip install -r requirements.txt
# Or standard pip
pip install -r requirements.txt
Verify Installation
# Run the test suite
pytest
# Generate a test dataset
python -m src.data_generation.scripts.generate_dataset --n_circuits 5
Quick Start
1. Generate a Dataset
# Generate 100 circuits with default settings
python -m src.data_generation.scripts.generate_dataset
# Custom: 500 circuits, 2-10 gates, 3 qubits
python -m src.data_generation.scripts.generate_dataset \
--n_circuits 500 \
--min_gates 2 \
--max_gates 10 \
--n_qubits 3 \
--output_file my_dataset.jsonl
2. Optimize a Circuit
# Set your API key
export OPENROUTER_API_KEY="sk-or-..."
# Optimize a simple circuit
python -m src.model_training.cli.predict \
--input_circuit "H 0 ; CNOT 0 1 ; H 0"
# With custom examples
python -m src.model_training.cli.predict \
--input_circuit "X 0 ; X 0 ; Y 1" \
--example "H 0 ; CNOT 0 1 ; H 0||CNOT 0 1" \
--example "X 0 ; X 0 ; Y 1||Y 1"
Data Generation Module
The src/data_generation/ package handles creating random quantum circuits,
simulating them, and saving structured datasets in JSON Lines format.
Each generated circuit record contains:
| Field | Type | Description |
|---|---|---|
raw_circuit | string | Cirq circuit string representation |
operations | list[dict] | Gate operations with type, qubits, exponent |
num_gates | int | Non-measurement gate count |
simulation_counts | dict | Measurement histogram from noisy simulation |
optimized_circuit | string | Cirq-optimized circuit string |
Circuit Generation
circuit_generation.py provides the core circuit creation logic using Cirq.
Key Classes & Functions
QuantumConfig
Constants for default circuit parameters:
| Constant | Value | Description |
|---|---|---|
N_QUBITS | 5 | Default number of qubits |
MIN_GATES | 1 | Minimum gates per circuit |
MAX_GATES | 5 | Maximum gates per circuit |
DEFAULT_NOISE | 0.01 | Default noise level |
generate_random_circuit(qubits, n_gates, gate_set=None)
Creates a random quantum circuit. Default gate set: X, Y, Z, H (single-qubit) and CNOT, CZ (two-qubit). Appends a measurement on all qubits.
import cirq
from src.data_generation.qc.circuit_generation import generate_random_circuit
qubits = [cirq.GridQubit(0, i) for i in range(3)]
circuit = generate_random_circuit(qubits, n_gates=5)
print(circuit)
GateOperationData
Frozen dataclass for serializing gate operations: gate_type, qubits_repr, exponent.
circuit_to_operations_data(circuit)
Converts a Cirq circuit to a list of GateOperationData objects and returns the non-measurement gate count.
Simulation
simulation.py provides two simulation modes for quantum circuits.
simulate_with_noise(circuit, noise, noise_model, repetitions)
Simulates a circuit under noise and returns measurement histograms.
| Parameter | Default | Description |
|---|---|---|
noise | 0.01 | Noise probability (0โ1) |
noise_model | "depolarize" | Options: depolarize, bit_flip, phase_flip |
repetitions | 1000 | Number of measurement shots |
simulate_statevector(circuit)
Simulates without noise, returning a dictionary of computational basis states to probabilities. Filters out probabilities below 1e-10.
from src.data_generation.qc.simulation import simulate_with_noise, simulate_statevector
# Noisy simulation
counts = simulate_with_noise(circuit, noise=0.05, noise_model="bit_flip")
# Noiseless statevector
probs = simulate_statevector(circuit)
print(probs) # {'state_000': 0.125, 'state_001': 0.125, ...}
Cirq Optimization
optimization.py wraps Cirq's built-in optimize_for_target_gateset routine.
optimize_circuit(circuit, qubits, gateset=None)
Optimizes a circuit for a target gateset. Defaults to cirq.CZTargetGateset() if none specified.
from src.data_generation.qc.optimization import optimize_circuit
import cirq
qubits = [cirq.GridQubit(0, i) for i in range(3)]
circuit = cirq.Circuit([cirq.H(q) for q in qubits])
optimized = optimize_circuit(circuit, qubits)
# Custom gateset
optimized_sqrt = optimize_circuit(circuit, qubits, gateset=cirq.SqrtIswapTargetGateset())
Model Training Module
The src/model_training/ package handles LLM-powered quantum circuit optimization
using in-context learning. Currently supports OpenRouter as the primary provider.
How It Works
- Provide input/output circuit examples (e.g.,
"H 0 ; CNOT 0 1 ; H 0" โ "CNOT 0 1") - The examples are formatted into a prompt with clear "Unoptimized/Optimized" pairs
- The target circuit is appended as the final "Unoptimized" entry
- The LLM generates the "Optimized" output using the learned pattern
- The optimized circuit string is returned
OpenRouter Integration
openrouter_optimizer.py handles API communication with OpenRouter's chat completions endpoint.
Authentication
The API key is resolved in this order:
OPENROUTER_API_KEYenvironment variable~/.api-openrouterfile (containing the key on one line)
optimize_circuit_with_openrouter(...)
| Parameter | Type | Description |
|---|---|---|
unoptimized_circuit_string | str | Circuit to optimize (e.g., "H 0 ; CNOT 0 1") |
examples | list[tuple] | List of (input, output) example pairs |
model | str | None | Model override (defaults to ~/.model-openrouter or "openrouter/free") |
timeout | int | HTTP timeout in seconds (default: 60) |
Returns the optimized circuit string. Raises ValueError for invalid inputs or missing API key, RuntimeError for API failures.
CLI Interface
The unified CLI (src.model_training.cli.predict) provides a single entry point
for circuit optimization.
Usage
python -m src.model_training.cli.predict [OPTIONS]
Required:
--input_circuit STR Circuit string (e.g., "H 0 ; CNOT 0 1 ; H 0")
Options:
--provider STR Provider name (default: openrouter)
--model STR Override model name
--timeout INT HTTP timeout in seconds (default: 60)
--example STR Add example as "input||output" (repeatable)
--verbose, -v Enable DEBUG logging
Examples
# Basic optimization with defaults
python -m src.model_training.cli.predict \
--input_circuit "H 0 ; CNOT 0 1 ; H 0"
# With custom examples and verbose output
python -m src.model_training.cli.predict \
--input_circuit "X 0 ; X 0 ; Y 1" \
--example "H 0 ; CNOT 0 1 ; H 0||CNOT 0 1" \
--example "X 0 ; X 0 ; Y 1||Y 1" \
--timeout 120 \
--verbose
# Override model
python -m src.model_training.cli.predict \
--provider openrouter \
--model "deepseek/deepseek-chat-v3-0324" \
--input_circuit "H 0 ; CNOT 0 1 ; H 0"
--example flags are provided, the CLI uses
two built-in examples: "H 0 ; CNOT 0 1 ; H 0" โ "CNOT 0 1" and
"X 0 ; X 0 ; Y 1" โ "Y 1".
API Reference
Data Generation โ qc.circuit_generation
| Symbol | Type | Description |
|---|---|---|
QuantumConfig | class | Constants: N_QUBITS, MIN_GATES, MAX_GATES, DEFAULT_NOISE |
GateOperationData | dataclass | Frozen dataclass: gate_type, qubits_repr, exponent |
generate_random_circuit(qubits, n_gates, gate_set=None) | function | Returns cirq.Circuit with random gates + measurement |
gate_operation_to_data(op) | function | Converts cirq.Operation โ GateOperationData |
circuit_to_operations_data(circuit) | function | Returns (list[GateOperationData], gate_count) |
Data Generation โ qc.simulation
| Symbol | Type | Description |
|---|---|---|
simulate_with_noise(circuit, noise, noise_model, repetitions) | function | Returns dict[int, int] measurement histogram |
simulate_statevector(circuit) | function | Returns dict[str, float] state probabilities |
Data Generation โ qc.optimization
| Symbol | Type | Description |
|---|---|---|
optimize_circuit(circuit, qubits, gateset=None) | function | Optimizes via Cirq CZTargetGateset (default) |
Data Generation โ scripts.generate_dataset
| Symbol | Type | Description |
|---|---|---|
generate_qc_dict(qubits, n_gates, noise_level) | function | Returns dict with raw_circuit, operations, num_gates, simulation_counts, optimized_circuit |
generate_dataset(n_circuits, qubits, min_gates, max_gates, noise_level) | function | Returns list of circuit dicts |
Model Training โ openrouter_optimizer
| Symbol | Type | Description |
|---|---|---|
optimize_circuit_with_openrouter(circuit_str, examples, model, timeout) | function | Returns optimized circuit string via OpenRouter API |
resolve_openrouter_api_key() | function | Returns API key from env or ~/.api-openrouter |
Model Training โ config
| Symbol | Type | Description |
|---|---|---|
DEFAULT_OPENROUTER_MODEL | str | "openrouter/free" |
OPENROUTER_API_URL | str | OpenRouter chat completions endpoint |
DEFAULT_TIMEOUT | int | 60 seconds |
resolve_openrouter_model(explicit=None) | function | Resolves model from arg, ~/.model-openrouter, or fallback |
Model Training โ utils
| Symbol | Type | Description |
|---|---|---|
validate_circuit_string(circuit_str) | function | Validates circuit format against known gates |
parse_examples(examples_str) | function | Parses "input||output" strings into tuples |
format_circuit_for_display(circuit_str, max_length=50) | function | Truncates long circuit strings for display |
setup_logging(verbose, level) | function | Configures logging level |
Configuration
API Keys
| Provider | Environment Variable | Fallback File |
|---|---|---|
| OpenRouter | OPENROUTER_API_KEY | ~/.api-openrouter |
Model Selection
Override default models by creating dotfiles in your home directory:
# Set default OpenRouter model
echo "deepseek/deepseek-chat-v3-0324" > ~/.model-openrouter
H, X, Y, Z, CNOT,
CX, CZ, S, T, RX,
RY, RZ
Testing
The project uses pytest with Hypothesis for property-based testing.
Running Tests
# Run all tests
pytest
# Run data generation tests
pytest src/data_generation/tests/
# Run with verbose output
pytest -v
Test Coverage
| Module | Tests | Approach |
|---|---|---|
| Circuit generation | Property-based (Hypothesis) | Validates gate counts, measurement presence across random inputs |
| Gate serialization | Unit tests | Verifies GateOperationData conversion accuracy |
| Noise simulation | Unit tests | Tests depolarize, bit_flip, phase_flip models |
| Statevector simulation | Unit tests | Verifies probability sum โ 1.0 |
| Dataset generation | Unit + CLI tests | Tests JSONL output, subprocess CLI invocation |
License
This project is licensed under the MIT No Attribution (MIT-0) license.
MIT No Attribution
Copyright 2025 WaifuAI
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.