qc-parallelizer 1.0.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.
- qc_parallelizer-1.0.0/.github/workflows/publish.yml +41 -0
- qc_parallelizer-1.0.0/.gitignore +174 -0
- qc_parallelizer-1.0.0/.pre-commit-config.yaml +35 -0
- qc_parallelizer-1.0.0/PKG-INFO +97 -0
- qc_parallelizer-1.0.0/README.md +79 -0
- qc_parallelizer-1.0.0/notebooks/parallel-circuits.ipynb +570 -0
- qc_parallelizer-1.0.0/notebooks/parallelizer-full.drawio.png +0 -0
- qc_parallelizer-1.0.0/pyproject.toml +49 -0
- qc_parallelizer-1.0.0/setup.cfg +4 -0
- qc_parallelizer-1.0.0/src/qc_parallelizer/__init__.py +1 -0
- qc_parallelizer-1.0.0/src/qc_parallelizer/base.py +35 -0
- qc_parallelizer-1.0.0/src/qc_parallelizer/generic/backendtools.py +14 -0
- qc_parallelizer-1.0.0/src/qc_parallelizer/generic/circuittools.py +240 -0
- qc_parallelizer-1.0.0/src/qc_parallelizer/generic/generic.py +45 -0
- qc_parallelizer-1.0.0/src/qc_parallelizer/generic/layouts.py +246 -0
- qc_parallelizer-1.0.0/src/qc_parallelizer/packing.py +298 -0
- qc_parallelizer-1.0.0/src/qc_parallelizer/parallelizer.py +302 -0
- qc_parallelizer-1.0.0/src/qc_parallelizer/postprocessing.py +176 -0
- qc_parallelizer-1.0.0/src/qc_parallelizer/transpiling.py +227 -0
- qc_parallelizer-1.0.0/src/qc_parallelizer.egg-info/PKG-INFO +97 -0
- qc_parallelizer-1.0.0/src/qc_parallelizer.egg-info/SOURCES.txt +27 -0
- qc_parallelizer-1.0.0/src/qc_parallelizer.egg-info/dependency_links.txt +1 -0
- qc_parallelizer-1.0.0/src/qc_parallelizer.egg-info/requires.txt +12 -0
- qc_parallelizer-1.0.0/src/qc_parallelizer.egg-info/top_level.txt +1 -0
- qc_parallelizer-1.0.0/tests/__init__.py +0 -0
- qc_parallelizer-1.0.0/tests/benchmark_parallelizer.py +208 -0
- qc_parallelizer-1.0.0/tests/test_common.py +62 -0
- qc_parallelizer-1.0.0/tests/test_parallelizer.py +58 -0
- qc_parallelizer-1.0.0/tests/utils.py +77 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
name: Upload package to PyPI
|
|
2
|
+
|
|
3
|
+
on: push
|
|
4
|
+
|
|
5
|
+
jobs:
|
|
6
|
+
build:
|
|
7
|
+
runs-on: ubuntu-latest
|
|
8
|
+
steps:
|
|
9
|
+
- uses: actions/checkout@v4
|
|
10
|
+
- name: Set up Python
|
|
11
|
+
uses: actions/setup-python@v5
|
|
12
|
+
with:
|
|
13
|
+
python-version: "3.10"
|
|
14
|
+
- name: Install build
|
|
15
|
+
run: python3 -m pip install build --user
|
|
16
|
+
- name: Build package
|
|
17
|
+
run: python3 -m build
|
|
18
|
+
- name: Store distribution packages
|
|
19
|
+
uses: actions/upload-artifact@v4
|
|
20
|
+
with:
|
|
21
|
+
name: dist
|
|
22
|
+
path: ./dist
|
|
23
|
+
publish-to-pypi:
|
|
24
|
+
runs-on: ubuntu-latest
|
|
25
|
+
if: startsWith(github.ref, 'refs/tags/')
|
|
26
|
+
needs:
|
|
27
|
+
- build
|
|
28
|
+
environment:
|
|
29
|
+
name: pypi
|
|
30
|
+
url: https://pypi.org/p/qc-parallelizer
|
|
31
|
+
permissions:
|
|
32
|
+
id-token: write
|
|
33
|
+
steps:
|
|
34
|
+
- name: Download dist
|
|
35
|
+
uses: actions/download-artifact@v4
|
|
36
|
+
with:
|
|
37
|
+
name: dist
|
|
38
|
+
path: ./dist
|
|
39
|
+
- name: Publish to PyPI
|
|
40
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
41
|
+
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
develop-eggs/
|
|
13
|
+
dist/
|
|
14
|
+
downloads/
|
|
15
|
+
eggs/
|
|
16
|
+
.eggs/
|
|
17
|
+
lib/
|
|
18
|
+
lib64/
|
|
19
|
+
parts/
|
|
20
|
+
sdist/
|
|
21
|
+
var/
|
|
22
|
+
wheels/
|
|
23
|
+
share/python-wheels/
|
|
24
|
+
*.egg-info/
|
|
25
|
+
.installed.cfg
|
|
26
|
+
*.egg
|
|
27
|
+
MANIFEST
|
|
28
|
+
|
|
29
|
+
# PyInstaller
|
|
30
|
+
# Usually these files are written by a python script from a template
|
|
31
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
32
|
+
*.manifest
|
|
33
|
+
*.spec
|
|
34
|
+
|
|
35
|
+
# Installer logs
|
|
36
|
+
pip-log.txt
|
|
37
|
+
pip-delete-this-directory.txt
|
|
38
|
+
|
|
39
|
+
# Unit test / coverage reports
|
|
40
|
+
htmlcov/
|
|
41
|
+
.tox/
|
|
42
|
+
.nox/
|
|
43
|
+
.coverage
|
|
44
|
+
.coverage.*
|
|
45
|
+
.cache
|
|
46
|
+
nosetests.xml
|
|
47
|
+
coverage.xml
|
|
48
|
+
*.cover
|
|
49
|
+
*.py,cover
|
|
50
|
+
.hypothesis/
|
|
51
|
+
.pytest_cache/
|
|
52
|
+
cover/
|
|
53
|
+
|
|
54
|
+
# Translations
|
|
55
|
+
*.mo
|
|
56
|
+
*.pot
|
|
57
|
+
|
|
58
|
+
# Django stuff:
|
|
59
|
+
*.log
|
|
60
|
+
local_settings.py
|
|
61
|
+
db.sqlite3
|
|
62
|
+
db.sqlite3-journal
|
|
63
|
+
|
|
64
|
+
# Flask stuff:
|
|
65
|
+
instance/
|
|
66
|
+
.webassets-cache
|
|
67
|
+
|
|
68
|
+
# Scrapy stuff:
|
|
69
|
+
.scrapy
|
|
70
|
+
|
|
71
|
+
# Sphinx documentation
|
|
72
|
+
docs/_build/
|
|
73
|
+
|
|
74
|
+
# PyBuilder
|
|
75
|
+
.pybuilder/
|
|
76
|
+
target/
|
|
77
|
+
|
|
78
|
+
# Jupyter Notebook
|
|
79
|
+
.ipynb_checkpoints
|
|
80
|
+
|
|
81
|
+
# IPython
|
|
82
|
+
profile_default/
|
|
83
|
+
ipython_config.py
|
|
84
|
+
|
|
85
|
+
# pyenv
|
|
86
|
+
# For a library or package, you might want to ignore these files since the code is
|
|
87
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
88
|
+
# .python-version
|
|
89
|
+
|
|
90
|
+
# pipenv
|
|
91
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
92
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
93
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
94
|
+
# install all needed dependencies.
|
|
95
|
+
#Pipfile.lock
|
|
96
|
+
|
|
97
|
+
# UV
|
|
98
|
+
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
|
|
99
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
100
|
+
# commonly ignored for libraries.
|
|
101
|
+
#uv.lock
|
|
102
|
+
|
|
103
|
+
# poetry
|
|
104
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
|
105
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
106
|
+
# commonly ignored for libraries.
|
|
107
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
|
108
|
+
#poetry.lock
|
|
109
|
+
|
|
110
|
+
# pdm
|
|
111
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
|
112
|
+
#pdm.lock
|
|
113
|
+
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
|
114
|
+
# in version control.
|
|
115
|
+
# https://pdm.fming.dev/latest/usage/project/#working-with-version-control
|
|
116
|
+
.pdm.toml
|
|
117
|
+
.pdm-python
|
|
118
|
+
.pdm-build/
|
|
119
|
+
|
|
120
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
|
121
|
+
__pypackages__/
|
|
122
|
+
|
|
123
|
+
# Celery stuff
|
|
124
|
+
celerybeat-schedule
|
|
125
|
+
celerybeat.pid
|
|
126
|
+
|
|
127
|
+
# SageMath parsed files
|
|
128
|
+
*.sage.py
|
|
129
|
+
|
|
130
|
+
# Environments
|
|
131
|
+
.env
|
|
132
|
+
.venv
|
|
133
|
+
env/
|
|
134
|
+
venv/
|
|
135
|
+
ENV/
|
|
136
|
+
env.bak/
|
|
137
|
+
venv.bak/
|
|
138
|
+
|
|
139
|
+
# Spyder project settings
|
|
140
|
+
.spyderproject
|
|
141
|
+
.spyproject
|
|
142
|
+
|
|
143
|
+
# Rope project settings
|
|
144
|
+
.ropeproject
|
|
145
|
+
|
|
146
|
+
# mkdocs documentation
|
|
147
|
+
/site
|
|
148
|
+
|
|
149
|
+
# mypy
|
|
150
|
+
.mypy_cache/
|
|
151
|
+
.dmypy.json
|
|
152
|
+
dmypy.json
|
|
153
|
+
|
|
154
|
+
# Pyre type checker
|
|
155
|
+
.pyre/
|
|
156
|
+
|
|
157
|
+
# pytype static type analyzer
|
|
158
|
+
.pytype/
|
|
159
|
+
|
|
160
|
+
# Cython debug symbols
|
|
161
|
+
cython_debug/
|
|
162
|
+
|
|
163
|
+
# PyCharm
|
|
164
|
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
|
165
|
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
|
166
|
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
|
167
|
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
|
168
|
+
#.idea/
|
|
169
|
+
|
|
170
|
+
# Ruff stuff:
|
|
171
|
+
.ruff_cache/
|
|
172
|
+
|
|
173
|
+
# PyPI configuration file
|
|
174
|
+
.pypirc
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
3
|
+
rev: v4.6.0
|
|
4
|
+
hooks:
|
|
5
|
+
- id: check-yaml
|
|
6
|
+
- id: end-of-file-fixer
|
|
7
|
+
- id: trailing-whitespace
|
|
8
|
+
- id: check-executables-have-shebangs
|
|
9
|
+
- id: debug-statements
|
|
10
|
+
- id: mixed-line-ending
|
|
11
|
+
|
|
12
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
13
|
+
rev: v0.5.2
|
|
14
|
+
hooks:
|
|
15
|
+
- id: ruff
|
|
16
|
+
args: [ --fix ]
|
|
17
|
+
types_or: [ python, pyi, jupyter ]
|
|
18
|
+
- id: ruff-format
|
|
19
|
+
types_or: [ python, pyi, jupyter ]
|
|
20
|
+
|
|
21
|
+
- repo: https://github.com/asottile/add-trailing-comma
|
|
22
|
+
rev: v3.1.0
|
|
23
|
+
hooks:
|
|
24
|
+
- id: add-trailing-comma
|
|
25
|
+
|
|
26
|
+
- repo: https://github.com/asottile/pyupgrade
|
|
27
|
+
rev: v3.16.0
|
|
28
|
+
hooks:
|
|
29
|
+
- id: pyupgrade
|
|
30
|
+
args: [ --py310-plus ]
|
|
31
|
+
|
|
32
|
+
- repo: https://github.com/kynan/nbstripout
|
|
33
|
+
rev: 0.7.1
|
|
34
|
+
hooks:
|
|
35
|
+
- id: nbstripout
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: qc-parallelizer
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: A module for optimally combining and distributing quantum circuits
|
|
5
|
+
Author-email: Henri Ahola <henri.ahola@vtt.fi>
|
|
6
|
+
Requires-Python: >=3.10
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
Requires-Dist: qiskit==0.45.3
|
|
9
|
+
Provides-Extra: tests
|
|
10
|
+
Requires-Dist: qiskit-iqm==13.7; extra == "tests"
|
|
11
|
+
Requires-Dist: pytest; extra == "tests"
|
|
12
|
+
Requires-Dist: pytest-cov; extra == "tests"
|
|
13
|
+
Provides-Extra: notebooks
|
|
14
|
+
Requires-Dist: qiskit-iqm==13.7; extra == "notebooks"
|
|
15
|
+
Requires-Dist: ipykernel; extra == "notebooks"
|
|
16
|
+
Requires-Dist: matplotlib; extra == "notebooks"
|
|
17
|
+
Requires-Dist: pylatexenc; extra == "notebooks"
|
|
18
|
+
|
|
19
|
+
# Quantum Circuit Parallelizer
|
|
20
|
+
|
|
21
|
+
A Python module for optimally combining and distributing quantum circuits. See the
|
|
22
|
+
[included notebooks](./notebooks/) for examples and more information. In summary, the motivation
|
|
23
|
+
for this module comes from frequent underutilization of increasingly large quantum processors. The
|
|
24
|
+
module processes several independent circuits into a smaller set of wider, combined circuits, which
|
|
25
|
+
it then runs on available backends in parallel. All of this happens behind the scenes, so ideally
|
|
26
|
+
the user can treat the module's functionality as a parallelized drop-in replacement for Qiskit's
|
|
27
|
+
`backend.run()`.
|
|
28
|
+
|
|
29
|
+
Here is a brief and basic example:
|
|
30
|
+
|
|
31
|
+
```python
|
|
32
|
+
# Define or load a number of circuits.
|
|
33
|
+
from qiskit import QuantumCircuit
|
|
34
|
+
circuits = [QuantumCircuit(...), QuantumCircuit(...), ...]
|
|
35
|
+
|
|
36
|
+
# Define backends for circuit execution. These can be any Qiskit-compatible backend objects, but
|
|
37
|
+
# here we define two simulators that mimic IQM's 5-qubit Adonis architechture.
|
|
38
|
+
import iqm.qiskit_iqm as iqm
|
|
39
|
+
backends = [iqm.IQMFakeAdonis(), iqm.IQMFakeAdonis()]
|
|
40
|
+
|
|
41
|
+
# Parallelize and execute. This call will
|
|
42
|
+
# 1. determine how to combine the circuits and for which backends, and
|
|
43
|
+
# 2. submit jobs to the backends.
|
|
44
|
+
import qc_parallelizer as parallelizer
|
|
45
|
+
job = parallelizer.execute(circuits, backends=backends)
|
|
46
|
+
|
|
47
|
+
# Fetch and handle results. This plots the first circuit's result histogram, for example.
|
|
48
|
+
results = job.results()
|
|
49
|
+
qiskit.visualization.plot_histogram(result[0].get_counts())
|
|
50
|
+
# Information on the parallelization and underlying jobs is also available.
|
|
51
|
+
print(f"On average, {job.info.avg_circuits_per_backend} circuits were placed per backend.")
|
|
52
|
+
print("Job IDs:")
|
|
53
|
+
for job_id in job.job_id():
|
|
54
|
+
print(f" - {job_id}")
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
For an operational overview, see this diagram:
|
|
58
|
+
|
|
59
|
+

|
|
60
|
+
|
|
61
|
+
## Development setup
|
|
62
|
+
|
|
63
|
+
For the following commands, a virtual environment or equivalent isolation is recommended. This can
|
|
64
|
+
be done with Conda, for example, with
|
|
65
|
+
```bash
|
|
66
|
+
conda create --name parallelizer python=3.10 pip # note the Python version!
|
|
67
|
+
conda activate parallelizer
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
The package can then be installed from a local copy of the directory by running
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
pip install -e .
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
from the repository root. If you additionally wish to run tests or the provided notebook(s), you
|
|
77
|
+
can install dependencies for those with
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
pip install .[tests]
|
|
81
|
+
# and/or
|
|
82
|
+
pip install .[notebooks]
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Testing
|
|
86
|
+
|
|
87
|
+
Running all tests is as simple as installing the required dependencie (`.[tests]`) and running
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
pytest
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
from the repository root. Additionally, there is a benchmarking script in the `tests/` directory.
|
|
94
|
+
|
|
95
|
+
## Authors
|
|
96
|
+
|
|
97
|
+
- **Henri Ahola** - henri.ahola@vtt.fi
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# Quantum Circuit Parallelizer
|
|
2
|
+
|
|
3
|
+
A Python module for optimally combining and distributing quantum circuits. See the
|
|
4
|
+
[included notebooks](./notebooks/) for examples and more information. In summary, the motivation
|
|
5
|
+
for this module comes from frequent underutilization of increasingly large quantum processors. The
|
|
6
|
+
module processes several independent circuits into a smaller set of wider, combined circuits, which
|
|
7
|
+
it then runs on available backends in parallel. All of this happens behind the scenes, so ideally
|
|
8
|
+
the user can treat the module's functionality as a parallelized drop-in replacement for Qiskit's
|
|
9
|
+
`backend.run()`.
|
|
10
|
+
|
|
11
|
+
Here is a brief and basic example:
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
# Define or load a number of circuits.
|
|
15
|
+
from qiskit import QuantumCircuit
|
|
16
|
+
circuits = [QuantumCircuit(...), QuantumCircuit(...), ...]
|
|
17
|
+
|
|
18
|
+
# Define backends for circuit execution. These can be any Qiskit-compatible backend objects, but
|
|
19
|
+
# here we define two simulators that mimic IQM's 5-qubit Adonis architechture.
|
|
20
|
+
import iqm.qiskit_iqm as iqm
|
|
21
|
+
backends = [iqm.IQMFakeAdonis(), iqm.IQMFakeAdonis()]
|
|
22
|
+
|
|
23
|
+
# Parallelize and execute. This call will
|
|
24
|
+
# 1. determine how to combine the circuits and for which backends, and
|
|
25
|
+
# 2. submit jobs to the backends.
|
|
26
|
+
import qc_parallelizer as parallelizer
|
|
27
|
+
job = parallelizer.execute(circuits, backends=backends)
|
|
28
|
+
|
|
29
|
+
# Fetch and handle results. This plots the first circuit's result histogram, for example.
|
|
30
|
+
results = job.results()
|
|
31
|
+
qiskit.visualization.plot_histogram(result[0].get_counts())
|
|
32
|
+
# Information on the parallelization and underlying jobs is also available.
|
|
33
|
+
print(f"On average, {job.info.avg_circuits_per_backend} circuits were placed per backend.")
|
|
34
|
+
print("Job IDs:")
|
|
35
|
+
for job_id in job.job_id():
|
|
36
|
+
print(f" - {job_id}")
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
For an operational overview, see this diagram:
|
|
40
|
+
|
|
41
|
+

|
|
42
|
+
|
|
43
|
+
## Development setup
|
|
44
|
+
|
|
45
|
+
For the following commands, a virtual environment or equivalent isolation is recommended. This can
|
|
46
|
+
be done with Conda, for example, with
|
|
47
|
+
```bash
|
|
48
|
+
conda create --name parallelizer python=3.10 pip # note the Python version!
|
|
49
|
+
conda activate parallelizer
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
The package can then be installed from a local copy of the directory by running
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
pip install -e .
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
from the repository root. If you additionally wish to run tests or the provided notebook(s), you
|
|
59
|
+
can install dependencies for those with
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
pip install .[tests]
|
|
63
|
+
# and/or
|
|
64
|
+
pip install .[notebooks]
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Testing
|
|
68
|
+
|
|
69
|
+
Running all tests is as simple as installing the required dependencie (`.[tests]`) and running
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
pytest
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
from the repository root. Additionally, there is a benchmarking script in the `tests/` directory.
|
|
76
|
+
|
|
77
|
+
## Authors
|
|
78
|
+
|
|
79
|
+
- **Henri Ahola** - henri.ahola@vtt.fi
|