Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
6c992d5
feat: implement randomized compiling
erichulburd Jun 2, 2026
1a3954c
feat: bit shifts
erichulburd Jun 4, 2026
d0dabf2
chore: convert to pyquil construction
erichulburd Jun 4, 2026
e4ca441
chore: ruff formatting and fixes
erichulburd Jun 4, 2026
2a45412
chore: generators to tuples and pyquil docstrings
erichulburd Jun 4, 2026
1041b60
chore: cleanup randomized compiling api
erichulburd Jun 8, 2026
b47404e
fix: verify final memory with readout randomization
erichulburd Jun 8, 2026
2aaf753
refactor: verifying final memory
erichulburd Jun 9, 2026
de4f0f4
refactor: configure readout randomization unitary angles
erichulburd Jun 9, 2026
cb6dcce
feat: support pauli frame tracking
erichulburd Jun 9, 2026
fdb60cb
refactor: pauli conjugates map types
erichulburd Jun 9, 2026
b12838f
feat: support extern signatures
erichulburd Jun 9, 2026
5d28994
refactor: use simulation matrices to verify final memory
erichulburd Jun 9, 2026
1283397
test: test randomized compiling
erichulburd Jun 10, 2026
9ea5011
test: add table test for lfsr_v1_next
erichulburd Jun 10, 2026
ab06411
refactor: simplify randomized compiling loops
erichulburd Jun 11, 2026
142bd38
fix: randomized compiling final memory verification
erichulburd Jun 12, 2026
cdccf9e
fix: do not shift before seed transitions
erichulburd Jun 12, 2026
67610a2
refactor: pauli cursor as enum
erichulburd Jun 12, 2026
c7bbbcf
test: do not declare final unitary layer with readout randomization
erichulburd Jun 12, 2026
afb50c3
feat: support global readout randomization source
erichulburd Jun 12, 2026
97c1ee9
test: add snapshot tests for randomized compiling
erichulburd Jun 12, 2026
3eaae4b
test: name syrupy snapshots
erichulburd Jun 12, 2026
928f08a
test: cleanup comments and file writes
erichulburd Jun 12, 2026
10461df
chore: delete old qpu module
erichulburd Jun 12, 2026
c2e7177
chore: remove hypothesis and pyrefly
erichulburd Jun 12, 2026
63ac2e4
chore: clean up formatting
erichulburd Jun 12, 2026
0f1b41b
chore: ignore pyrefly configuration
erichulburd Jun 12, 2026
ed4b66a
refactor: make extern signatures and randomized compiling module public
erichulburd Jun 12, 2026
03ffb9a
refactor: for python 3.9 compatibility
erichulburd Jun 12, 2026
594b826
chore: mypy fixes
erichulburd Jun 12, 2026
a1cd2a7
chore: address osv scanner issues
erichulburd Jun 12, 2026
b412df1
test: delete live qpu test
erichulburd Jun 12, 2026
b4de342
test: ensure python 3.9 and qpu support
erichulburd Jun 12, 2026
8cfe454
chore: update quil release candidate
erichulburd Jun 12, 2026
5f1b54c
fix: unitaries must be same length as twirled unitaries
erichulburd Jun 12, 2026
d4f61f2
chore: bump version for prerelease
erichulburd Jun 12, 2026
0be125f
docs: fix pauli previous pauli index
erichulburd Jun 12, 2026
3808d18
fix: account for base cycle length of 1 or >= paulis per value
erichulburd Jun 16, 2026
d9248d5
test: support randomized compiling unit and e2e shared test cases
erichulburd Jun 16, 2026
11e00a3
chore: ignore ruff cache
erichulburd Jun 16, 2026
372b189
test: support live qpu access via command line
erichulburd Jun 16, 2026
f45d116
docs: add live qpu tests to pr checklist
erichulburd Jun 16, 2026
9556795
chore: bump release candidate
erichulburd Jun 16, 2026
a8b0c0a
chore: add bleach to osv scanner ignore
erichulburd Jun 16, 2026
695e52e
chore: delete obsolete syrupy snapshots
erichulburd Jun 16, 2026
513e5eb
ci: force github rerun failed jobs
erichulburd Jun 16, 2026
dfec527
test: revert override qcs config comment
erichulburd Jun 16, 2026
01f376e
chore: bump release candidate version
erichulburd Jun 16, 2026
bca9109
refactor: support non-twirled qubits
erichulburd Jun 17, 2026
5411300
refactor: do not include call instruction for identity pairs
erichulburd Jun 17, 2026
7eee8de
refactor: default twirled unitaries to unitary source
erichulburd Jun 17, 2026
d6ded7e
chore: ruff import ordering
erichulburd Jun 18, 2026
a22d5e8
test: fix override qcs config import
erichulburd Jun 18, 2026
d24f9e5
refactor: remove readout randomization as core feature
erichulburd Jun 23, 2026
c2f932b
test: update fixtures for readout randomization
erichulburd Jun 23, 2026
e8dea0f
refactor: new interface for apply readout randomization
erichulburd Jun 24, 2026
49e65cd
fix: mypy types and other ci fixes
erichulburd Jun 24, 2026
4a656a6
chore: bump release candidate version
erichulburd Jun 24, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Insert your PR description here. Thanks for [contributing][contributing] to pyQu
- [ ] All changes to code are covered via unit tests.
- [ ] Parameters and return values have type hints with [PEP 484 syntax][pep-484].
- [ ] Functions and classes have useful [Sphinx-style][sphinx] docstrings.
- [ ] Live QPU tests have run via `pytest test --live-qpu-access` by myself or a reviewer.
- [ ] (New Feature) The [docs][docs] have been updated accordingly.
- [ ] (Bugfix) The associated issue is referenced above using [auto-close keywords][auto-close].

Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ jobs:
go install github.com/google/osv-scanner/cmd/osv-scanner@latest
- name: Run OSV scanner
run: |
osv-scanner --lockfile=./poetry.lock
osv-scanner scan --config=.osv-scanner.toml --lockfile=./poetry.lock

test-doctest:
name: Run Doctests
Expand Down Expand Up @@ -153,7 +153,7 @@ jobs:
poetry run make test
- name: Report Coverage
if: matrix.python-version == '3.11' && github.event_name == 'pull_request'
continue-on-error: true
continue-on-error: true
uses: orgoro/coverage@v3.1
with:
coverageFile: coverage.xml
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -184,10 +184,13 @@ fabric.properties
### MyPi ###
.mypy_cache

.ruff_cache

### VSCode ###
**/.vscode/

pyrightconfig.json
pyrefly.toml

# unversioned developer notes
.scratch/
Expand Down
72 changes: 72 additions & 0 deletions .osv-scanner.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# See https://github.com/rigetti/pyquil/issues/1852
# pillow 11.3.0 - locked for python <3.11 via matplotlib (docs extra)
# Fixed in pillow 12.x which requires python >=3.10
[[IgnoredVulns]]
id = "GHSA-5xmw-vc9v-4wf2"
reason = "pillow 11.3.0 only resolved for python <3.11 (docs extra); fix requires dropping python 3.9 support"

[[IgnoredVulns]]
id = "GHSA-cfh3-3jmp-rvhc"
reason = "pillow 11.3.0 only resolved for python <3.11 (docs extra); fix requires dropping python 3.9 support"

[[IgnoredVulns]]
id = "GHSA-pwv6-vv43-88gr"
reason = "pillow 11.3.0 only resolved for python <3.11 (docs extra); fix requires dropping python 3.9 support"

[[IgnoredVulns]]
id = "GHSA-r73j-pqj5-w3x7"
reason = "pillow 11.3.0 only resolved for python <3.11 (docs extra); fix requires dropping python 3.9 support"

[[IgnoredVulns]]
id = "GHSA-whj4-6x5x-4v2j"
reason = "pillow 11.3.0 only resolved for python <3.11 (docs extra); fix requires dropping python 3.9 support"

[[IgnoredVulns]]
id = "PYSEC-2026-165"
reason = "pillow 11.3.0 only resolved for python <3.11 (docs extra); fix requires dropping python 3.9 support"

[[IgnoredVulns]]
id = "GHSA-wjx4-4jcj-g98j"
reason = "pillow 11.3.0 only resolved for python <3.11 (docs extra); fix requires dropping python 3.9 support"

# pytest 8.4.2 - dev dependency only, not shipped to users
# Fixed in pytest 9.x but requires bumping pytest-benchmark and other plugins
[[IgnoredVulns]]
id = "GHSA-6w46-j5rx-g56g"
reason = "pytest is a dev dependency only; fix requires bumping to pytest ^9 and updating plugins"

# requests 2.32.5 - locked for python <3.11 via sphinx (docs extra)
# Fixed in requests 2.34.x which requires python >=3.10
[[IgnoredVulns]]
id = "GHSA-gc5v-m9x4-r6x2"
reason = "requests 2.32.5 only resolved for python <3.11 (docs extra); fix requires dropping python 3.9 support"

# urllib3 2.6.3 - locked for python <3.11 via sphinx/requests (docs extra)
# Fixed in urllib3 2.7.x which requires python >=3.10
[[IgnoredVulns]]
id = "PYSEC-2026-142"
reason = "urllib3 2.6.3 only resolved for python <3.11 (docs extra); fix requires dropping python 3.9 support"

[[IgnoredVulns]]
id = "GHSA-mf9v-mfxr-j63j"
reason = "urllib3 2.6.3 only resolved for python <3.11 (docs extra); fix requires dropping python 3.9 support"

[[IgnoredVulns]]
id = "PYSEC-2026-141"
reason = "urllib3 2.6.3 only resolved for python <3.11 (docs extra); fix requires dropping python 3.9 support"

[[IgnoredVulns]]
id = "GHSA-qccp-gfcp-xxvc"
reason = "urllib3 2.6.3 only resolved for python <3.11 (docs extra); fix requires dropping python 3.9 support"

[[IgnoredVulns]]
id = "GHSA-8rfp-98v4-mmr6"
reason = "bleach update requires python >= 3.10"

[[IgnoredVulns]]
id = "GHSA-gj48-438w-jh9v"
reason = "bleach update requires python >= 3.10"

[[IgnoredVulns]]
id = "GHSA-6v7p-g79w-8964"
reason = "requires dropping rpcq dependency"
469 changes: 336 additions & 133 deletions poetry.lock

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "pyquil"
version = "4.17.1-rc.0"
version = "4.18.0-rc.4"
description = "A Python library for creating Quantum Instruction Language (Quil) programs."
authors = ["Rigetti Computing <softapps@rigetti.com>"]
readme = "README.md"
Expand Down Expand Up @@ -28,7 +28,7 @@ scipy = "^1.11"
rpcq = "^3.11.0"
networkx = ">=2.5"
qcs-sdk-python = ">=0.20.1,<0.22"
quil = ">=0.15.3,<0.18"
quil = "0.18.0rc2"
packaging = ">=23.1"
deprecated = "^1.2.14"
types-deprecated = "^1.2.9.3"
Expand Down
Empty file added pyquil/_qpu/__init__.py
Empty file.
199 changes: 199 additions & 0 deletions pyquil/_qpu/extern_signatures.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
from quil import instructions as inst

from pyquil.quilbase import Pragma

_NUMBER_PAULI_PAIRS = 16


def build_extern_function_signatures() -> dict[str, Pragma]:
"""Build and return a map from extern function name to the corresponding EXTERN pragma.

These signtures reflect extern function signatures publicly supported by various pyQuil features, such as
but not limited to randomized compiling.
"""
destination = inst.ExternParameter(
"destination",
True,
inst.ExternParameterType.from_variable_length_vector(inst.ScalarType.Real),
)
unitary_angles = inst.ExternParameter(
"unitary_angles",
False,
inst.ExternParameterType.from_variable_length_vector(inst.ScalarType.Real),
)
angle_offset = inst.ExternParameter(
"angle_offset",
False,
inst.ExternParameterType.from_scalar(inst.ScalarType.Integer),
)
pauli_set = inst.ExternParameterType.from_scalar(inst.ScalarType.Integer)
pauli_index = inst.ExternParameterType.from_scalar(inst.ScalarType.Integer)
is_pauli_left = inst.ExternParameter(
"is_pauli_left", False, inst.ExternParameterType.from_scalar(inst.ScalarType.Bit)
)
pauli_conjugates_map = inst.ExternParameter(
"pauli_conjugates_map",
False,
inst.ExternParameterType.from_fixed_length_vector(inst.Vector(inst.ScalarType.Integer, _NUMBER_PAULI_PAIRS)),
)
pauli_literal = inst.ExternParameterType.from_scalar(inst.ScalarType.Integer)
signatures = [
(
"merge_zxzxz_unitary_with_paulis_reference_conjugate",
inst.ExternSignature(
parameters=[
destination,
unitary_angles,
angle_offset,
inst.ExternParameter("next_paulis", False, pauli_set),
inst.ExternParameter("next_pauli_index", False, pauli_index),
inst.ExternParameter("previous_paulis_left", False, pauli_set),
inst.ExternParameter("previous_pauli_left_index", False, pauli_index),
inst.ExternParameter("previous_paulis_right", False, pauli_set),
inst.ExternParameter("previous_pauli_right_index", False, pauli_index),
is_pauli_left,
pauli_conjugates_map,
],
return_type=None,
).to_quil(),
),
(
"merge_zxzxz_unitary_with_paulis_literal_literal",
inst.ExternSignature(
parameters=[
destination,
unitary_angles,
angle_offset,
inst.ExternParameter("next_pauli", False, pauli_literal),
inst.ExternParameter("conjugate_pauli", False, pauli_literal),
],
return_type=None,
).to_quil(),
),
(
"merge_zxzxz_unitary_with_paulis_literal_conjugate",
inst.ExternSignature(
parameters=[
destination,
unitary_angles,
angle_offset,
inst.ExternParameter("next_pauli", False, pauli_literal),
inst.ExternParameter("previous_paulis_left", False, pauli_set),
inst.ExternParameter("previous_pauli_left_index", False, pauli_index),
inst.ExternParameter("previous_paulis_right", False, pauli_set),
inst.ExternParameter("previous_pauli_right_index", False, pauli_index),
is_pauli_left,
pauli_conjugates_map,
],
return_type=None,
).to_quil(),
),
(
"merge_zxzxz_unitary_with_paulis_reference_literal",
inst.ExternSignature(
parameters=[
destination,
unitary_angles,
angle_offset,
inst.ExternParameter("next_paulis", False, pauli_set),
inst.ExternParameter("next_pauli_index", False, pauli_index),
inst.ExternParameter("conjugate_pauli", False, pauli_literal),
],
return_type=None,
).to_quil(),
),
(
"merge_zxzxz_unitary_with_paulis_literal_reference",
inst.ExternSignature(
parameters=[
destination,
unitary_angles,
angle_offset,
inst.ExternParameter("next_pauli", False, pauli_literal),
inst.ExternParameter("previous_paulis", False, pauli_set),
inst.ExternParameter("previous_pauli_index", False, pauli_index),
],
return_type=None,
).to_quil(),
),
(
"merge_zxzxz_unitary_with_paulis_reference_reference",
inst.ExternSignature(
parameters=[
destination,
unitary_angles,
angle_offset,
inst.ExternParameter("next_paulis", False, pauli_set),
inst.ExternParameter("next_pauli_index", False, pauli_index),
inst.ExternParameter("previous_paulis", False, pauli_set),
inst.ExternParameter("previous_pauli_index", False, pauli_index),
],
return_type=None,
).to_quil(),
),
(
"prng_set_seed_and_step",
inst.ExternSignature(
parameters=[
inst.ExternParameter("seed", False, inst.ExternParameterType.from_scalar(inst.ScalarType.Integer))
],
return_type=inst.ScalarType.Integer,
).to_quil(),
),
(
"prng_step",
inst.ExternSignature(
parameters=[],
return_type=inst.ScalarType.Integer,
).to_quil(),
),
(
"if_then_else_integer",
inst.ExternSignature(
parameters=[
inst.ExternParameter("condition", False, inst.ExternParameterType.from_scalar(inst.ScalarType.Bit)),
inst.ExternParameter(
"true_value", False, inst.ExternParameterType.from_scalar(inst.ScalarType.Integer)
),
inst.ExternParameter(
"false_value", False, inst.ExternParameterType.from_scalar(inst.ScalarType.Integer)
),
],
return_type=inst.ScalarType.Integer,
).to_quil(),
),
(
"if_then_else_real",
inst.ExternSignature(
parameters=[
inst.ExternParameter("condition", False, inst.ExternParameterType.from_scalar(inst.ScalarType.Bit)),
inst.ExternParameter(
"true_value", False, inst.ExternParameterType.from_scalar(inst.ScalarType.Real)
),
inst.ExternParameter(
"false_value", False, inst.ExternParameterType.from_scalar(inst.ScalarType.Real)
),
],
return_type=inst.ScalarType.Real,
).to_quil(),
),
(
"choose_random_real_sub_regions",
inst.ExternSignature(
parameters=[
inst.ExternParameter(
"destination", True, inst.ExternParameterType.from_variable_length_vector(inst.ScalarType.Real)
),
inst.ExternParameter(
"source", False, inst.ExternParameterType.from_variable_length_vector(inst.ScalarType.Real)
),
inst.ExternParameter(
"sub_region_size", False, inst.ExternParameterType.from_scalar(inst.ScalarType.Integer)
),
inst.ExternParameter("seed", True, inst.ExternParameterType.from_scalar(inst.ScalarType.Integer)),
],
return_type=None,
).to_quil(),
),
]
return {name: Pragma("EXTERN", [name], signature) for name, signature in signatures}
Loading
Loading