qledger 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- qledger-0.1.0/.github/workflows/ci.yml +38 -0
- qledger-0.1.0/.gitignore +34 -0
- qledger-0.1.0/CITATION.cff +46 -0
- qledger-0.1.0/CONTRIBUTING.md +44 -0
- qledger-0.1.0/LICENSE +21 -0
- qledger-0.1.0/PKG-INFO +293 -0
- qledger-0.1.0/README.md +249 -0
- qledger-0.1.0/docs/README.md +36 -0
- qledger-0.1.0/examples/01_basic_usage.py +51 -0
- qledger-0.1.0/examples/02_cross_framework.py +38 -0
- qledger-0.1.0/examples/03_circuit_versioning.py +52 -0
- qledger-0.1.0/examples/04_benchmarking.py +49 -0
- qledger-0.1.0/examples/05_noise_profiling.py +65 -0
- qledger-0.1.0/pyproject.toml +83 -0
- qledger-0.1.0/qledger/__init__.py +32 -0
- qledger-0.1.0/qledger/adapters/__init__.py +20 -0
- qledger-0.1.0/qledger/adapters/base.py +174 -0
- qledger-0.1.0/qledger/adapters/cirq_adapter.py +368 -0
- qledger-0.1.0/qledger/adapters/pennylane_adapter.py +306 -0
- qledger-0.1.0/qledger/adapters/qiskit_adapter.py +407 -0
- qledger-0.1.0/qledger/adapters/registry.py +104 -0
- qledger-0.1.0/qledger/benchmarks/__init__.py +22 -0
- qledger-0.1.0/qledger/benchmarks/algorithmic.py +198 -0
- qledger-0.1.0/qledger/benchmarks/clops.py +143 -0
- qledger-0.1.0/qledger/benchmarks/quantum_volume.py +297 -0
- qledger-0.1.0/qledger/benchmarks/suite.py +217 -0
- qledger-0.1.0/qledger/cli/__init__.py +1 -0
- qledger-0.1.0/qledger/cli/main.py +289 -0
- qledger-0.1.0/qledger/core/__init__.py +5 -0
- qledger-0.1.0/qledger/core/engine.py +455 -0
- qledger-0.1.0/qledger/noise/__init__.py +5 -0
- qledger-0.1.0/qledger/noise/profiler.py +186 -0
- qledger-0.1.0/qledger/schema/__init__.py +26 -0
- qledger-0.1.0/qledger/schema/circuit.py +266 -0
- qledger-0.1.0/qledger/schema/gates.py +381 -0
- qledger-0.1.0/qledger/schema/noise.py +256 -0
- qledger-0.1.0/qledger/schema/result.py +159 -0
- qledger-0.1.0/qledger/storage/__init__.py +5 -0
- qledger-0.1.0/qledger/storage/database.py +544 -0
- qledger-0.1.0/qledger/versioning/__init__.py +5 -0
- qledger-0.1.0/qledger/versioning/tracker.py +260 -0
- qledger-0.1.0/tests/__init__.py +0 -0
- qledger-0.1.0/tests/integration/__init__.py +0 -0
- qledger-0.1.0/tests/integration/test_qiskit_pipeline.py +179 -0
- qledger-0.1.0/tests/unit/__init__.py +0 -0
- qledger-0.1.0/tests/unit/test_circuit.py +150 -0
- qledger-0.1.0/tests/unit/test_database.py +154 -0
- qledger-0.1.0/tests/unit/test_gates.py +67 -0
- qledger-0.1.0/tests/unit/test_noise.py +100 -0
- qledger-0.1.0/tests/unit/test_quantum_volume_sim.py +82 -0
- qledger-0.1.0/tests/unit/test_result.py +56 -0
- qledger-0.1.0/tests/unit/test_versioning.py +155 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
strategy:
|
|
13
|
+
fail-fast: false
|
|
14
|
+
matrix:
|
|
15
|
+
python-version: ["3.10", "3.11", "3.12", "3.13"]
|
|
16
|
+
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v4
|
|
19
|
+
|
|
20
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
21
|
+
uses: actions/setup-python@v5
|
|
22
|
+
with:
|
|
23
|
+
python-version: ${{ matrix.python-version }}
|
|
24
|
+
cache: pip
|
|
25
|
+
|
|
26
|
+
- name: Install package with dev extras
|
|
27
|
+
run: |
|
|
28
|
+
python -m pip install --upgrade pip
|
|
29
|
+
pip install -e ".[dev]"
|
|
30
|
+
|
|
31
|
+
- name: Lint (ruff)
|
|
32
|
+
run: ruff check .
|
|
33
|
+
|
|
34
|
+
- name: Type check (mypy --strict)
|
|
35
|
+
run: mypy qledger
|
|
36
|
+
|
|
37
|
+
- name: Run tests
|
|
38
|
+
run: pytest
|
qledger-0.1.0/.gitignore
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
__pycache__/
|
|
2
|
+
*.py[cod]
|
|
3
|
+
*$py.class
|
|
4
|
+
*.egg-info/
|
|
5
|
+
dist/
|
|
6
|
+
build/
|
|
7
|
+
*.egg
|
|
8
|
+
.eggs/
|
|
9
|
+
*.so
|
|
10
|
+
*.db
|
|
11
|
+
*.sqlite
|
|
12
|
+
*.sqlite3
|
|
13
|
+
.venv/
|
|
14
|
+
venv/
|
|
15
|
+
env/
|
|
16
|
+
.env
|
|
17
|
+
.pytest_cache/
|
|
18
|
+
.mypy_cache/
|
|
19
|
+
.ruff_cache/
|
|
20
|
+
htmlcov/
|
|
21
|
+
.coverage
|
|
22
|
+
*.cover
|
|
23
|
+
*.log
|
|
24
|
+
.idea/
|
|
25
|
+
.vscode/
|
|
26
|
+
.claude/settings.local.json
|
|
27
|
+
*.swp
|
|
28
|
+
*.swo
|
|
29
|
+
*~
|
|
30
|
+
.DS_Store
|
|
31
|
+
Thumbs.db
|
|
32
|
+
|
|
33
|
+
# Private brief — kept locally for sharing, not published to the repo
|
|
34
|
+
OVERVIEW.md
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# This CITATION.cff lets people cite QLedger correctly.
|
|
2
|
+
# GitHub reads this file and shows a "Cite this repository" button on the repo page,
|
|
3
|
+
# which exports BibTeX/APA automatically. See https://citation-file-format.github.io
|
|
4
|
+
cff-version: 1.2.0
|
|
5
|
+
message: "If you use QLedger in your research or software, please cite it using the metadata below."
|
|
6
|
+
title: "QLedger: The Universal Quantum Experiment Lifecycle Platform"
|
|
7
|
+
abstract: >-
|
|
8
|
+
QLedger is an open-source Python platform that executes quantum circuits across
|
|
9
|
+
Qiskit, Cirq, and PennyLane through a universal intermediate representation,
|
|
10
|
+
versions circuits with Git-like history and diffs, runs standardised benchmarks
|
|
11
|
+
(Quantum Volume, CLOPS, algorithmic fidelity), profiles hardware noise over time,
|
|
12
|
+
and persists every experiment in a single portable SQLite file for exact
|
|
13
|
+
reproducibility.
|
|
14
|
+
type: software
|
|
15
|
+
authors:
|
|
16
|
+
- given-names: Namash
|
|
17
|
+
family-names: Aggarwal
|
|
18
|
+
# orcid: "https://orcid.org/0000-0000-0000-0000" # add your ORCID iD if you have one
|
|
19
|
+
version: 0.1.0
|
|
20
|
+
date-released: 2026-06-06 # update to your actual release date
|
|
21
|
+
license: MIT
|
|
22
|
+
repository-code: "https://github.com/namashworks/qledger"
|
|
23
|
+
url: "https://github.com/namashworks/qledger"
|
|
24
|
+
keywords:
|
|
25
|
+
- quantum computing
|
|
26
|
+
- quantum circuits
|
|
27
|
+
- reproducibility
|
|
28
|
+
- experiment tracking
|
|
29
|
+
- benchmarking
|
|
30
|
+
- noise characterization
|
|
31
|
+
- version control
|
|
32
|
+
- qiskit
|
|
33
|
+
- cirq
|
|
34
|
+
- pennylane
|
|
35
|
+
|
|
36
|
+
# ----------------------------------------------------------------------------
|
|
37
|
+
# OPTIONAL — strongest form of citable credit:
|
|
38
|
+
# Archive a release on Zenodo (https://zenodo.org) to mint a permanent DOI,
|
|
39
|
+
# then uncomment and fill in the lines below. A DOI is what gets you cited in
|
|
40
|
+
# academic papers and gives your work a durable, referenceable identity.
|
|
41
|
+
# ----------------------------------------------------------------------------
|
|
42
|
+
# doi: "10.5281/zenodo.XXXXXXX"
|
|
43
|
+
# identifiers:
|
|
44
|
+
# - type: doi
|
|
45
|
+
# value: "10.5281/zenodo.XXXXXXX"
|
|
46
|
+
# description: "Archived snapshot of QLedger v0.1.0"
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Contributions are welcome. Here's how to get started.
|
|
4
|
+
|
|
5
|
+
## Setup
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
git clone https://github.com/namashworks/qledger.git
|
|
9
|
+
cd qledger
|
|
10
|
+
pip install -e ".[dev]"
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Development workflow
|
|
14
|
+
|
|
15
|
+
1. Create a feature branch from `main`.
|
|
16
|
+
2. Write your code and add tests.
|
|
17
|
+
3. Run the full check suite:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
pytest
|
|
21
|
+
ruff check .
|
|
22
|
+
mypy qledger
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
4. Open a pull request against `main`.
|
|
26
|
+
|
|
27
|
+
## Adding a new framework adapter
|
|
28
|
+
|
|
29
|
+
1. Create `qledger/adapters/<framework>_adapter.py`.
|
|
30
|
+
2. Implement the `BaseAdapter` interface (see `base.py`).
|
|
31
|
+
3. Add the `@AdapterRegistry.register` decorator.
|
|
32
|
+
4. Add the module path to `_ADAPTER_MODULES` in `registry.py`.
|
|
33
|
+
5. Add the framework as an optional dependency in `pyproject.toml`.
|
|
34
|
+
6. Add tests in `tests/integration/`.
|
|
35
|
+
|
|
36
|
+
## Code style
|
|
37
|
+
|
|
38
|
+
- [PEP 8](https://peps.python.org/pep-0008/) enforced by Ruff
|
|
39
|
+
- Type annotations on all public functions
|
|
40
|
+
- [NumPy-style](https://numpydoc.readthedocs.io/en/latest/format.html) docstrings
|
|
41
|
+
|
|
42
|
+
## Tests
|
|
43
|
+
|
|
44
|
+
All tests use in-memory SQLite (`:memory:`), so they're fast and require no external services. Integration tests that need a quantum framework are in `tests/integration/`.
|
qledger-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Namash Aggarwal
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
qledger-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: qledger
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: The universal quantum experiment lifecycle platform. Execute circuits across frameworks, track noise, benchmark hardware, and persist everything.
|
|
5
|
+
Project-URL: Homepage, https://github.com/namashworks/qledger
|
|
6
|
+
Project-URL: Repository, https://github.com/namashworks/qledger
|
|
7
|
+
Project-URL: Issues, https://github.com/namashworks/qledger/issues
|
|
8
|
+
Project-URL: Documentation, https://github.com/namashworks/qledger/tree/main/docs
|
|
9
|
+
Author: Namash Aggarwal
|
|
10
|
+
License: MIT
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: benchmarking,cirq,experiment-tracking,noise,pennylane,qiskit,quantum,quantum-computing,reproducibility,sqlite
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Intended Audience :: Science/Research
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Topic :: Scientific/Engineering :: Physics
|
|
22
|
+
Classifier: Typing :: Typed
|
|
23
|
+
Requires-Python: >=3.10
|
|
24
|
+
Provides-Extra: all
|
|
25
|
+
Requires-Dist: cirq-core>=1.3; extra == 'all'
|
|
26
|
+
Requires-Dist: pennylane>=0.35; extra == 'all'
|
|
27
|
+
Requires-Dist: qiskit-aer>=0.13; extra == 'all'
|
|
28
|
+
Requires-Dist: qiskit>=1.0; extra == 'all'
|
|
29
|
+
Provides-Extra: cirq
|
|
30
|
+
Requires-Dist: cirq-core>=1.3; extra == 'cirq'
|
|
31
|
+
Provides-Extra: dev
|
|
32
|
+
Requires-Dist: mypy>=1.10; extra == 'dev'
|
|
33
|
+
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
|
|
34
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
35
|
+
Requires-Dist: qiskit-aer>=0.13; extra == 'dev'
|
|
36
|
+
Requires-Dist: qiskit>=1.0; extra == 'dev'
|
|
37
|
+
Requires-Dist: ruff>=0.4; extra == 'dev'
|
|
38
|
+
Provides-Extra: pennylane
|
|
39
|
+
Requires-Dist: pennylane>=0.35; extra == 'pennylane'
|
|
40
|
+
Provides-Extra: qiskit
|
|
41
|
+
Requires-Dist: qiskit-aer>=0.13; extra == 'qiskit'
|
|
42
|
+
Requires-Dist: qiskit>=1.0; extra == 'qiskit'
|
|
43
|
+
Description-Content-Type: text/markdown
|
|
44
|
+
|
|
45
|
+
# QLedger
|
|
46
|
+
|
|
47
|
+
**The Universal Quantum Experiment Lifecycle Platform.**
|
|
48
|
+
|
|
49
|
+
Execute circuits across Qiskit, Cirq, and PennyLane. Track noise. Benchmark hardware. Version circuits. Persist everything in a portable SQLite file.
|
|
50
|
+
|
|
51
|
+
[](https://github.com/namashworks/qledger/actions/workflows/ci.yml)
|
|
52
|
+
[](LICENSE)
|
|
53
|
+
[](https://www.python.org/downloads/)
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Why QLedger?
|
|
58
|
+
|
|
59
|
+
The quantum computing ecosystem is **fragmented**. Every framework has its own circuit format, every backend returns results differently, and there's no standard way to track experiments, compare hardware, or reproduce results.
|
|
60
|
+
|
|
61
|
+
QLedger fixes this with a single platform that:
|
|
62
|
+
|
|
63
|
+
- **Runs circuits on any framework** — Qiskit, Cirq, PennyLane — through a universal adapter layer
|
|
64
|
+
- **Persists everything** — circuits, results, metadata, seeds, timing, noise profiles — in one portable `.db` file
|
|
65
|
+
- **Versions circuits** — git-like tracking of how your circuits evolve over time
|
|
66
|
+
- **Benchmarks hardware** — Quantum Volume, CLOPS, and algorithmic fidelity benchmarks with standardised scoring
|
|
67
|
+
- **Tracks noise** — capture T1/T2, gate fidelities, and readout errors over time to monitor hardware drift
|
|
68
|
+
- **Enables reproducibility** — every seed, every setting, every result is stored for exact replay
|
|
69
|
+
|
|
70
|
+
## Installation
|
|
71
|
+
|
|
72
|
+
> **Note:** PyPI release pending — until then, install from source (see below). The `pip install qledger` commands will work once the first release is published.
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
# Core only (no framework dependencies)
|
|
76
|
+
pip install qledger
|
|
77
|
+
|
|
78
|
+
# With specific frameworks
|
|
79
|
+
pip install qledger[qiskit]
|
|
80
|
+
pip install qledger[cirq]
|
|
81
|
+
pip install qledger[pennylane]
|
|
82
|
+
pip install qledger[all]
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
From source:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
git clone https://github.com/namashworks/qledger.git
|
|
89
|
+
cd qledger
|
|
90
|
+
pip install -e ".[dev]"
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Quick Start
|
|
94
|
+
|
|
95
|
+
```python
|
|
96
|
+
from qiskit import QuantumCircuit
|
|
97
|
+
from qledger import QLedger
|
|
98
|
+
|
|
99
|
+
with QLedger("my_research.db") as db:
|
|
100
|
+
# Create an experiment
|
|
101
|
+
exp_id = db.create_experiment("Bell States", tags=["entanglement"])
|
|
102
|
+
|
|
103
|
+
# Build and run a circuit — everything is saved automatically
|
|
104
|
+
qc = QuantumCircuit(2, 2)
|
|
105
|
+
qc.h(0)
|
|
106
|
+
qc.cx(0, 1)
|
|
107
|
+
qc.measure([0, 1], [0, 1])
|
|
108
|
+
|
|
109
|
+
result = db.run(qc, experiment_id=exp_id, shots=4096, seed_simulator=42)
|
|
110
|
+
|
|
111
|
+
print(result.counts) # {'00': 2009, '11': 2087}
|
|
112
|
+
print(result.probabilities) # {'00': 0.490, '11': 0.510}
|
|
113
|
+
print(result.most_frequent()) # '11'
|
|
114
|
+
print(result.entropy()) # ~1.000 (near-maximum for 2 equally likely outcomes)
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Core Features
|
|
118
|
+
|
|
119
|
+
### 1. Universal Circuit IR
|
|
120
|
+
|
|
121
|
+
Convert between frameworks seamlessly:
|
|
122
|
+
|
|
123
|
+
```python
|
|
124
|
+
# Qiskit -> Universal -> Cirq
|
|
125
|
+
cirq_circuit = db.convert(qiskit_circuit, from_framework="qiskit", to_framework="cirq")
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
The `UniversalCircuit` is a framework-agnostic intermediate representation with content hashing, validation, and full serialisation support.
|
|
129
|
+
|
|
130
|
+
### 2. Cross-Framework Execution
|
|
131
|
+
|
|
132
|
+
```python
|
|
133
|
+
# Run the same circuit on different backends
|
|
134
|
+
result_qiskit = db.run(qc, framework="qiskit", shots=4096)
|
|
135
|
+
result_cirq = db.run(cirq_circuit, framework="cirq", shots=4096)
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### 3. Circuit Versioning
|
|
139
|
+
|
|
140
|
+
Track circuit evolution like git tracks code:
|
|
141
|
+
|
|
142
|
+
```python
|
|
143
|
+
# Auto-versioned on every run, or manually:
|
|
144
|
+
db.version_circuit(circuit_id, modified_circuit, message="optimised CX count")
|
|
145
|
+
|
|
146
|
+
# View history
|
|
147
|
+
log = db.circuit_log(circuit_id)
|
|
148
|
+
|
|
149
|
+
# Diff between versions
|
|
150
|
+
diff = db.diff_circuit(circuit_id, version_a=1, version_b=3)
|
|
151
|
+
print(diff.summary_text()) # "+2 gates, -1 gates, depth: 5 -> 4"
|
|
152
|
+
|
|
153
|
+
# Restore any version
|
|
154
|
+
old_circuit = db.checkout_circuit(circuit_id, version=1)
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### 4. Standardised Benchmarks
|
|
158
|
+
|
|
159
|
+
```python
|
|
160
|
+
suite = db.benchmark(framework="qiskit")
|
|
161
|
+
|
|
162
|
+
# Quantum Volume
|
|
163
|
+
qv = suite.run_quantum_volume(backend=my_backend, max_depth=8)
|
|
164
|
+
print(f"Quantum Volume: {qv.details['quantum_volume']}")
|
|
165
|
+
|
|
166
|
+
# CLOPS (throughput)
|
|
167
|
+
clops = suite.run_clops(num_circuits=100, shots=1024)
|
|
168
|
+
print(f"CLOPS: {clops.score:.0f}")
|
|
169
|
+
|
|
170
|
+
# Algorithmic fidelity (GHZ, QFT)
|
|
171
|
+
ghz = suite.run_algorithmic(algorithm="ghz", qubit_range=(2, 10))
|
|
172
|
+
print(f"Average fidelity: {ghz.score:.4f}")
|
|
173
|
+
|
|
174
|
+
# Compare backends
|
|
175
|
+
comparison = suite.compare_backends("quantum_volume", ["backend_a", "backend_b"])
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### 5. Noise Profiling
|
|
179
|
+
|
|
180
|
+
```python
|
|
181
|
+
# Capture noise from a real backend
|
|
182
|
+
snapshot = db.capture_noise(backend, framework="qiskit")
|
|
183
|
+
|
|
184
|
+
print(f"Median T1: {snapshot.median_t1_us:.1f} us")
|
|
185
|
+
print(f"Avg CX error: {snapshot.average_cx_error:.4f}")
|
|
186
|
+
print(f"Avg readout error: {snapshot.average_readout_error:.4f}")
|
|
187
|
+
|
|
188
|
+
# Track drift over time
|
|
189
|
+
history = db.get_noise_history("ibm_kyoto")
|
|
190
|
+
|
|
191
|
+
# Find the best qubits
|
|
192
|
+
best = db.best_qubits("ibm_kyoto", count=5, metric="t1")
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### 6. Batch Execution
|
|
196
|
+
|
|
197
|
+
```python
|
|
198
|
+
results = db.run_batch(
|
|
199
|
+
[circuit_1, circuit_2, circuit_3],
|
|
200
|
+
experiment_name="Parameter Sweep",
|
|
201
|
+
names=["theta=0.1", "theta=0.5", "theta=1.0"],
|
|
202
|
+
shots=8192,
|
|
203
|
+
)
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### 7. Export
|
|
207
|
+
|
|
208
|
+
```python
|
|
209
|
+
# Export full experiment as JSON
|
|
210
|
+
data = db.export_experiment(exp_id)
|
|
211
|
+
|
|
212
|
+
# Includes: experiment metadata, all circuits (as UniversalCircuit JSON),
|
|
213
|
+
# all executions (with counts, timing, seeds), version history
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
## CLI
|
|
217
|
+
|
|
218
|
+
```bash
|
|
219
|
+
# List experiments
|
|
220
|
+
qledger experiments
|
|
221
|
+
|
|
222
|
+
# Show experiment details
|
|
223
|
+
qledger show 1
|
|
224
|
+
|
|
225
|
+
# List circuits with structural info
|
|
226
|
+
qledger circuits 1
|
|
227
|
+
|
|
228
|
+
# List executions with results
|
|
229
|
+
qledger executions --backend aer_simulator
|
|
230
|
+
|
|
231
|
+
# View circuit version history
|
|
232
|
+
qledger versions 1
|
|
233
|
+
|
|
234
|
+
# View benchmark results
|
|
235
|
+
qledger benchmarks --type quantum_volume
|
|
236
|
+
|
|
237
|
+
# View noise snapshots
|
|
238
|
+
qledger noise --backend ibm_kyoto
|
|
239
|
+
|
|
240
|
+
# Export experiment to JSON
|
|
241
|
+
qledger export 1 -o experiment.json
|
|
242
|
+
|
|
243
|
+
# List available framework adapters
|
|
244
|
+
qledger adapters
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
## Database Schema
|
|
248
|
+
|
|
249
|
+
Everything lives in a single SQLite file:
|
|
250
|
+
|
|
251
|
+
| Table | Purpose |
|
|
252
|
+
|---|---|
|
|
253
|
+
| `experiments` | Named containers with tags and descriptions |
|
|
254
|
+
| `circuits` | UniversalCircuit JSON, content hash, gate counts, depth |
|
|
255
|
+
| `executions` | Counts, probabilities, entropy, backend config, seeds, timing |
|
|
256
|
+
| `circuit_versions` | Version history with diffs and parent hashes |
|
|
257
|
+
| `noise_snapshots` | T1/T2, gate fidelities, readout errors per qubit |
|
|
258
|
+
| `benchmark_results` | QV, CLOPS, algorithmic scores with full parameters |
|
|
259
|
+
|
|
260
|
+
Foreign keys with `ON DELETE CASCADE`. WAL mode for concurrent reads.
|
|
261
|
+
|
|
262
|
+
## Architecture
|
|
263
|
+
|
|
264
|
+
```
|
|
265
|
+
qledger/
|
|
266
|
+
schema/ # Universal data models (circuit IR, results, noise)
|
|
267
|
+
gates.py # 30+ canonical gates with cross-framework aliases
|
|
268
|
+
circuit.py # UniversalCircuit with hashing, validation, depth calc
|
|
269
|
+
result.py # ExecutionResult with entropy, fidelity computation
|
|
270
|
+
noise.py # NoiseSnapshot, QubitProperties, GateFidelity
|
|
271
|
+
adapters/ # Framework adapters (Qiskit, Cirq, PennyLane)
|
|
272
|
+
base.py # Abstract adapter interface
|
|
273
|
+
registry.py # Lazy auto-discovery registry
|
|
274
|
+
storage/ # SQLite persistence layer
|
|
275
|
+
versioning/ # Git-like circuit version tracking with diffs
|
|
276
|
+
noise/ # Noise profiling and drift analysis
|
|
277
|
+
benchmarks/ # Quantum Volume, CLOPS, algorithmic benchmarks
|
|
278
|
+
core/ # Main QLedger engine
|
|
279
|
+
cli/ # Command-line interface
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
## Development
|
|
283
|
+
|
|
284
|
+
```bash
|
|
285
|
+
pip install -e ".[dev]"
|
|
286
|
+
pytest # 95 tests
|
|
287
|
+
ruff check . # Lint
|
|
288
|
+
mypy qledger # Type check
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
## License
|
|
292
|
+
|
|
293
|
+
[MIT](LICENSE)
|