Skip to content

Commit 4f47c12

Browse files
MarquessVkalzoo
andauthored
feat!: Program and Instruction APIs are backed by quil-rs (#1639)
* Foundational support for implementing Program with qcs-sdk-python (#1518) * tear out members, start replacing with rust API (WIP) * first pass as integrating with qcs_sdk.quil * fix low hanging fruit, introduce snapshot testing for passing tests, annotate others with improvements that need to be made * update poetry.lock * more test annotations, fixes, snapshots * deprecation warnings and cleanup * Gate tests and snapshots, pre-replacement with quil-rs * add test for FORKED gate * back Gate with RSGate * fix deprecated notice * test improvements * more cleanup * various cleanups * add more snaps * clean up program per feedback * feat!: The `calibrations` method on `Program` now only returns `DefCalibration`s. A `Program`s the `DefMeasureCalibrations` can be retrieved via the new `measure_calibrations` method. * update instruction handling logic * deprecate valid protoquil/quilt methods * add compatibility layer by overriding quil_rs.Gate superclass methods * remove gate __init__ method * remove old comments * revert defcal changes * safer type checking on conversion methods * simplify ParameterDesignator Type * forbidden metaclass shenanigans * Update pyquil/quil.py Co-authored-by: Kalan <[email protected]> * use deprecated decorator * update qcs-sdk-python dependency spec --------- Co-authored-by: Kalan <[email protected]> * V4 Setters for the Gate class (#1535) * add and test setters * use simple enum syntax * Use quil_rs for Calibrations (#1536) * setup test suite for DefCalibration * back DefCalibration with quil_rs.Calibration * fix metaclass implementation so all instruction types aren't recognized as the same * back DefCalibration with quil_rs.Calibration * setup DefMeasureCalibration tests * back DefMeasureCalibration with quil_rs.MeasureCalibrationDefinition * gate calibrations with quil_rs * more efficient handling of calibrations * setup Measurement tests * back Measurement with quil_rs * use calibration set api for calibrations * BREAKING CHANGE: DefMeasureCalibration now requires a MemoryReference * update tests * cleanup stale todos, match calibration logic * type hints for tests * remove redundant guard in match_calibrations Co-authored-by: Kalan <[email protected]> --------- Co-authored-by: Kalan <[email protected]> * Re-write `get_classical_addresses_from_quil_program` to use `quil-rs` (#1541) * BREAKING CHANGE: DefFrame and Frame are no longer dataclasses We've removed the @DataClass decorator from `DefFrame` and `Frame`. `Frame`s properties can now be edited. Most functionality should have been re-implemented, but breakages may be possible, depending on how much of the @DataClass functionality was being leveraged. * Use quil-rs FrameSet API and compatibility layer (#1543) * setup Frame and DefFrame test suites * add eq test * back Frame with quil_rs FrameDefinition * back DefFrame with quil_rs.FrameDefinition * fix flaky DefFrame snapshot tests * cleanup imports * "unfreeze" Frame properties * use FrameSet API and compatibility layer, with tests * update calibrations property as well * center_frequency -> CENTER-FREQUENCY * fix attribute names in DefFrame * update snapshot * BREAKING CHANGE: Setting the offsets property on `Declare` will raise a `ValueError` if no shared_region is set. * setup tests for Declare * BREAKING CHANGE: Setting the offsets property on ``Declare`` will raise if no shared_region is set. * update tests * add note * trust truthy/falsy values * BREAKING CHANGE: A `Program` that uses qubit or label placeholders cannot be pickled * V4 Program API: Back GateDef with GateDefinition (#1549) * setup DefGate test suite * add baseline tests for permutation and pauli gates * compatibility for paulis, expressions, back DefGate with GateDefinition * back DefPermutationGate with quil-rs * back DefGateByPaulis w/ quil-rs * better support Expressions * dont try to support Expressions * cleanup * update tests * combine int, float, and complex conversion * feat: Add DefCircuit * setup DefWaveform tests * back DefWaveform with quil-rs * update snapshot * clean up redudnant import * implement DefCircuit using quil-rs * add DefCircuit|Waveform to py instruction conversion method * update snapshot after instruction indentation fix * V4 Instruction API: Pragma, Reset, Fence, Delay (#1551) * setup Pragma tests * setup tests for Qubit * setup tests for Fence * back Pragma with quil_rs.Pragma * back Reset, ResetQubit, with quil-rs * Back Delay(Frames|Qubits) with quil-rs * update Delay implementation per feedback * back Fence, FenceAll, with quil-rs * remove unused snapshots, prints * update convers to rs/py instruction functions * better type for numpy numbers * cleanup, and assert ResetQubit qubit is not None * BREAKING CHANGE: The `pop` method has been removed from `Program` * remove to_headers * BREAKING CHANGE: The `pop` method has been removed from `Program` * remove to_headers arg * * BREAKING CHANGE: `TemplateWaveform` and its subclasses are no longer dataclasses. Most important functionality has been replaced so this change should be transparent for most use cases. * setup tests for Capture * setup tests for Pulse * create tests for RawCapture * add tests for template waveforms * add compatibility layer for TemplateWaveforms * back Capture with quil_rs * back Pulse with quil_rs * back RawCapture with quil_rs * BREAKING CHANGE: `TemplateWaveform` and its subclasses are no longer dataclasses. Most important functionality has been replaced so this change should be transparent for most use cases. * deprecation warning for TemplateWaveform and its subclasses, direct to new WaveformInvocation class * BREAKING CHANGE: SwapPhase has been renamed to SwapPhases * setup up tests for set/shift instructions * setup tests for SwapPhase * back frame mutation instructions with quil-rs * back SwapPhase with quil-rs * formatting * BREAKING CHANGE: SwapPhase has been renamed to SwapPhases * V4: Deprecate format parameter (#1566) * update mypy, fix various lints, deprecate format_parameter * returns variable length tuple * a few more lints * more lints * cant isinstance check with generics * V4: The rest of the non control-flow instructions (#1568) * ClassicalConvert tests * tests for Classical(Exchange|Load|Move) * ClassicalStore tests * test ClassicalComparison classes * test UnaryClassicalInstructions * Include implementation and test * Wait, Halt, Nop test and implementation * implement ClassicalConvert * re-implement ClassicalLoad * re-implement ClassicalStore * re-implement ClassicalComparison * re-implement Exchange * re-implement ClassicalUnary * back ClassicalMove, ClassicalExchange with quil-rs * fix recursive implementation of SimpleInstruction.__str__ * fix!: The `get_qubits` method on a `Gate` now returns a list so that ordering is always guaranteed. * update snapshots for test_main * add test annotations for test_noise.py * account for integer qubit in pragma arguments * Instruction API for BinaryOperations * update noise tests * resolve issues in test_quil.py, or update todo annotation * update rewrite_arithmetic * fix parser tests * annotate test_paulis_with_placeholders * update test_quantum_computer * annotate/fix test_quilt.py * update snapshots * BREAKING CHANGE: fill_placeholders has been removed as it is no longer used to expand calibrations * bump quil version * fix some tests * chore! Remove `parser` module (#1618) * chore!: Remove `parser` module. A `Program` can instead be constructed from a Quil program string directly. The full list of `AbstractInstruction`s is available on the `instructions` property. * fix flaky test * add parantheses to assertion * V4 Program API: De-dupe definitions when adding instructions to a Program (#1625) * wip - de-dupe based on abstract instruction * normalize incoming instructions ot quil-rs types * a lil more cleanup * update docstrings * bump qcs-sdk-python/quil * V4 Program API - Placeholders and Control Flow (#1633) * use to_quil() in out() methods * simplify inst * fix test_quilbase tests * fix other failing tests * make instructions consistent with v3 implementation * back Label with quil_rs * back LabelPlaceholder with quil_rs * back QubitPlaceholders with quil_rs * fix off by 1 in test * checkpoint: update/fix many tests * checkpoint: all tests passing! * use renamed method * some mypy fixes * replace deprecation with deprecated * import sphinx decorator * fix mypy lints and dangling todos * get docs building * fix doctests * update doctests * simplify pauli from_list * instrucion->instruction * use body_instructions property * update a few old references to instructions * one more * add resolve_placeholders_with_custom_resolvers method * various small fixes * Remove support for QubitPlaceholders as Pragma arguments * fix typo Co-authored-by: Kalan <[email protected]> * Update CHANGELOG.md Co-authored-by: Kalan <[email protected]> * Update CHANGELOG.md Co-authored-by: Kalan <[email protected]> * Update CHANGELOG.md Co-authored-by: Kalan <[email protected]> * Update CHANGELOG.md Co-authored-by: Kalan <[email protected]> * remove duplicate entry * ignore sphinx warnings * grammar * update qcs-sdk-python --------- Co-authored-by: Kalan <[email protected]> * satisfy lints * impl repr * type hint capitalization * add HALT back in * update dev dependencies, quiet down internal depreaction warnings in test suite * update CHANGELOG * more changelog tweaks * explicitly specify `toml` as a dev dependency --------- Co-authored-by: Kalan <[email protected]>
1 parent 721698f commit 4f47c12

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+6295
-4461
lines changed

CHANGELOG.md

+34-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,27 @@ The 4.0 release of pyQuil migrates its core functionality into Rigetti's latest
1212
- Python 3.7 is no longer supported.
1313
- The environment variable overrides for `quilc` and `QVM` URLs have been renamed to `QCS_APPLICATIONS_QUILC_URL` and `QCS_APPLICATIONS_QVM_URL`, respectively.
1414
- The `QuantumComputer`'s `run` method now takes an optional `memory_map` parameter. This mapping takes memory region names to a list of values to use for a run. This replaces the ability to use `write_memory` on `Program`s.
15-
- `Pragma("DELAY", ...)` will now raise a parser error because it generates invalid Quil. Use the `Delay` instruction instead.
15+
- `Program` and instructions have been re-written using the `quil` package. Much of the API remains the same, with the following exceptions:
16+
- `SwapPhase` has been renamed to `SwapPhases`
17+
- `TemplateWaveform` and its subclasses are no longer `@dataclass`es.
18+
- `DefFrame` and `Frame` are no longer `@dataclass`es.
19+
- The `pop` method has been removed from `Program`.
20+
- A `Program` that uses `QubitPlaceholder`s or `LabelPlaceholder`s can no longer be pickled
21+
- `DefMeasureCalibration` now requires a `MemoryReference`.
22+
- `fill_placeholders` has been removed since it is no longer needed to expand calibrations.
23+
- The `get_qubits` method on `Gate` now returns a `list` so that ordering is guaranteed.
24+
- Setting the `offsets` property on `Declare` will raise a `ValueError` if no `shared_region` is set.
25+
- When converting to Quil, a `Program` automatically places `DECLARE`s at the top of the program.
26+
- The `parser` module has been removed. Parsing now happens by initializing a `Program` with the program string you want to be parsed.
27+
- `PRAGMA` instructions can no longer have a directive that conflicts with a Quil keyword. If you were using directives like `DELAY` or `FENCE`, consider using the respective Quil-T instructions instead.
28+
- `QubitPlaceholders` can no longer be used in `PRAGMA` instructions.
29+
- `DefGate` and the other gate definition instructions will no longer accept names that conflict with Quil keywords.
30+
- `Program#get_qubits()` will raise a `TypeError` if any of the qubits in the program are not a fixed index.
31+
- A `Program`s `LabelPlaceholder`s are no longer resolved automatically when getting its instructions. Use the `resolve_label_placeholders` method to do it explicitly. Note that the `if_then` and `while_do` methods will add `LabelPlaceholder`s to your program.
32+
- There may be some minor differences in how instructions are converted to a Quil string. These differences should only be cosmetic and should not affect the behavior of a program. However, they may break unit tests or other code that rely on specific formatting of programs.
33+
- The `pyquil.quil.get_default_qubit_mapping` function for getting a mapping of `QubitPlaceholders` to resolved indices has been removed. Generating a default mapping is handled automatically by the placeholder resolving methods.
34+
- The `JumpConditional` base class has been removed, use `JumpWhen` and/or `JumpUnless` directly instead.
35+
- The `Program` class automatically sorts `DECLARE` instructions to the top of the Program when converting to Quil.
1636

1737
### Features
1838

@@ -24,11 +44,24 @@ The 4.0 release of pyQuil migrates its core functionality into Rigetti's latest
2444
- The new `QPUCompilerAPIOptions` class provides can now be used to customize how a program is compiled against a QPU.
2545
- The `diagnostics` module has been introduced with a `get_report` function that will gather information on the currently running pyQuil
2646
installation, perform diagnostics checks, and return a summary.
47+
- `Program` has new methods for resolving Qubit and Label Placeholders in a program.
48+
- `QubitPlaceholders` can now be used in programs that also use fixed or variable qubits.
2749
- `QAMExecutionResult` now has a `raw_readout_data` property that can be used to get the raw form of readout data returned from the executor.
50+
- `WaveformInvocation` has been added as a simpler, more flexible class for invoking waveforms.
51+
- Added two new instruction classes:
52+
- The `Include` class for `INCLUDE` instructions.
53+
- The `DefCircuit` class `DEFCIRCUIT` instructions.
54+
- The `Program.copy` method now performs a deep copy.
2855

2956
### Deprecations
3057

3158
- The `QAMExecutionResult` `readout_data` property has been deprecated to avoid confusion with the new `raw_readout_data` property. Use the `register_map` property instead.
59+
- The `indices` flag on the `get_qubits` method on `Program`s and instruction classes continues to work, but will be removed in future versions. A separate `get_qubit_indices` method has been added to get indices. In future versions, `get_qubits` will only return a list of `QubitDesignator`s.
60+
- The `is_protoquil`, `is_supported_on_qpu` methods on `Program` and the `validate_supported_quil` function will always return `True`. These methods were never reliable as they were implemented as client-side checks that don't necessarily reflect the latest available features on Rigetti compilers or QPUs. It's safe to stop using these functions and rely on the API to tell you if a program isn't supported.
61+
- `percolate_declares` is a no-op and will be removed in future versions. `Program` now “percolates” declares automatically.
62+
- `merge_programs` continues to work, but will be removed in future versions, use `Program` addition instead.
63+
- The `format_parameter` function continues to work, but will be removed in future versions.
64+
- The `WaveformReference` and `TemplateWaveform` classes continue to work, but will be removed in future versions. The new `WaveformInvocation` should be used instead.
3265

3366
## 3.5.4
3467

docs/source/advanced_usage.rst

+22-22
Original file line numberDiff line numberDiff line change
@@ -146,15 +146,13 @@ where using ``QubitPlaceholder``\ s comes in.
146146
.. testoutput:: placeholders
147147
:hide:
148148

149-
H {q...}
150-
CNOT {q...} {q...}
149+
H Placeholder(QubitPlaceholder(0x...))
150+
CNOT Placeholder(QubitPlaceholder(0x...)) Placeholder(QubitPlaceholder(0x...))
151151

152152
.. parsed-literal::
153153
154-
H {q4402789176}
155-
CNOT {q4402789176} {q4402789120}
156-
157-
If you try to use this program directly, it will not work
154+
H Placeholder(QubitPlaceholder(0x600002DEB5B0))
155+
CNOT Placeholder(QubitPlaceholder(0x600002DEB5B0)) Placeholder(QubitPlaceholder(0x600002DEABB0))
158156
159157
..
160158
Could not make this a doctest because it would keep failing. ``doctest`` is supposed to match the
@@ -272,20 +270,21 @@ loop by following these steps:
272270

273271
# Run inner_loop in a loop until flag_register is 0
274272
outer_loop.while_do(flag_register, inner_loop)
273+
outer_loop.resolve_label_placeholders()
275274

276275
print(outer_loop)
277276

278277
.. testoutput:: control-flow
279278

280279
DECLARE flag_register BIT[1]
281-
MOVE flag_register 1
282-
LABEL @START1
283-
JUMP-UNLESS @END2 flag_register
280+
MOVE flag_register[0] 1
281+
LABEL @START_0
282+
JUMP-UNLESS @END_0 flag_register[0]
284283
X 0
285284
H 0
286-
MEASURE 0 flag_register
287-
JUMP @START1
288-
LABEL @END2
285+
MEASURE 0 flag_register[0]
286+
JUMP @START_0
287+
LABEL @END_0
289288

290289
Notice that the ``outer_loop`` program applied a Quil instruction directly to a
291290
classical register. There are several classical commands that can be used in this fashion:
@@ -323,21 +322,22 @@ method.
323322

324323
# Measure qubit 0 into our readout register
325324
branching_prog += MEASURE(0, ro)
325+
branching_prog.resolve_label_placeholders()
326326

327327
print(branching_prog)
328328

329329
.. testoutput:: control-flow
330330

331-
DECLARE test_register BIT[1]
332331
DECLARE ro BIT[1]
332+
DECLARE test_register BIT[1]
333333
H 1
334-
MEASURE 1 test_register
335-
JUMP-WHEN @THEN1 test_register
336-
JUMP @END2
337-
LABEL @THEN1
334+
MEASURE 1 test_register[0]
335+
JUMP-WHEN @THEN_0 test_register[0]
336+
JUMP @END_0
337+
LABEL @THEN_0
338338
X 0
339-
LABEL @END2
340-
MEASURE 0 ro
339+
LABEL @END_0
340+
MEASURE 0 ro[0]
341341

342342
We can run this program a few times to see what we get in the readout register ``ro``.
343343

@@ -437,7 +437,7 @@ The following shows an instructive example of all three.
437437

438438
Quil to compute exp[iX] on qubit 0:
439439
H 0
440-
RZ(-2.0) 0
440+
RZ(-2) 0
441441
H 0
442442

443443
``exponential_map`` returns a function allowing you to fill in a multiplicative
@@ -461,12 +461,12 @@ value for :math:`\alpha`.
461461

462462
1:
463463
H 0
464-
RZ(-2.0) 0
464+
RZ(-2) 0
465465
H 0
466466

467467
2:
468468
H 0
469-
RZ(-4.0) 0
469+
RZ(-4) 0
470470
H 0
471471

472472
To take it one step further, you can use :ref:`parametric_compilation` with ``exponential_map``. For instance:

docs/source/conf.py

+6
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,12 @@
105105
}
106106
}
107107

108+
suppress_warnings = [
109+
# TODO: Re-enable these warnings once Sphinx resolves this open issue:
110+
# https://github.com/sphinx-doc/sphinx/issues/4961
111+
"ref.python",
112+
]
113+
108114
# fun little hack to always build the rst changelog from the markdown
109115

110116
dirname = os.path.dirname(__file__)

docs/source/exercises.rst

+3-3
Original file line numberDiff line numberDiff line change
@@ -179,10 +179,10 @@ We can see what this program looks like in Quil notation with ``print(qft(0, 1,
179179

180180
SWAP 0 2
181181
H 0
182-
CPHASE(-pi/2) 0 1
182+
CPHASE(-1.5707963267948966) 0 1
183183
H 1
184-
CPHASE(-pi/4) 0 2
185-
CPHASE(-pi/2) 1 2
184+
CPHASE(-0.7853981633974483) 0 2
185+
CPHASE(-1.5707963267948966) 1 2
186186
H 2
187187

188188
Part c: Execute the QFT

docs/source/noise.rst

+4-4
Original file line numberDiff line numberDiff line change
@@ -617,12 +617,12 @@ The Idiomatic pyQuil Program
617617
.. testoutput:: decoherence
618618

619619
H 0
620-
RX(pi/2) 1
620+
RX(1.5707963267948966) 1
621621
CNOT 0 1
622-
RZ(2*pi/3) 1
622+
RZ(2.0943951023931953) 1
623623
CNOT 0 1
624624
H 0
625-
RX(-pi/2) 1
625+
RX(-1.5707963267948966) 1
626626

627627

628628
The Compiled Program
@@ -1165,10 +1165,10 @@ Pauli-Z moments that indicate the qubit correlations are corrupted (and correcte
11651165

11661166
.. testoutput:: readout-noise
11671167

1168+
DECLARE ro BIT[3]
11681169
PRAGMA READOUT-POVM 0 "(0.85 0.050000000000000044 0.15000000000000002 0.95)"
11691170
PRAGMA READOUT-POVM 1 "(0.8 0.09999999999999998 0.19999999999999996 0.9)"
11701171
PRAGMA READOUT-POVM 2 "(0.9 0.15000000000000002 0.09999999999999998 0.85)"
1171-
DECLARE ro BIT[3]
11721172
H 0
11731173
CNOT 0 1
11741174
CNOT 1 2

docs/source/programs_and_gates.rst

+3-3
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,7 @@ matrix representation of the gate. For example, below we define a
434434

435435
.. testoutput:: define-gates
436436

437-
DEFGATE SQRT-X:
437+
DEFGATE SQRT-X AS MATRIX:
438438
0.5+0.5i, 0.5-0.5i
439439
0.5-0.5i, 0.5+0.5i
440440

@@ -535,7 +535,7 @@ Some gates can be compactly represented as a permutation. For example, ``CCNOT``
535535
[0, 0, 0, 0, 0, 0, 1, 0]
536536
])
537537

538-
ccnot_gate = DefGate("CCNOT", ccnot_matrix)
538+
ccnot_gate = DefGate("MATRIX_CCNOT", ccnot_matrix)
539539

540540
# etc
541541

@@ -546,7 +546,7 @@ It can equivalently be defined by the permutation
546546
import numpy as np
547547
from pyquil.quilbase import DefPermutationGate
548548

549-
ccnot_gate = DefPermutationGate("CCNOT", [0, 1, 2, 3, 4, 5, 7, 6])
549+
ccnot_gate = DefPermutationGate("PERMUTATION_CCNOT", [0, 1, 2, 3, 4, 5, 7, 6])
550550

551551
# etc
552552

docs/source/troubleshooting.rst

+9-1
Original file line numberDiff line numberDiff line change
@@ -77,13 +77,21 @@ Collect debug information
7777

7878
3. Run your script with debug logging enabled by adding the following to the top of your script:
7979

80-
.. testcode:: python
80+
.. testcode:: debug
8181

8282
import logging
8383
logging.basicConfig(level=logging.DEBUG)
8484

8585
.. note:: For information on how to filter the logs, see the `qcs-sdk-python logging documentation <https://github.com/rigetti/qcs-sdk-rust/tree/main/crates/python#enabling-debug-logging>`_
8686

87+
.. testcode:: debug
88+
:hide:
89+
90+
import logging
91+
# Disable debug logging, otherwise doctests will run with
92+
# debug logging enabled.
93+
logging.basicConfig(level=logging.INFO)
94+
8795
If the problem still isn't clear, then we can help! Please file an issue
8896
on the `GitHub repo <https://github.com/rigetti/pyquil>`_ if it's an issue with pyQuil itself,
8997
or contact us at our `support page <https://rigetti.zendesk.com>`_ for problems with QCS. If applicable,

mypy.ini

-4
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,6 @@ no_implicit_reexport = False
2626

2727
plugins = numpy.typing.mypy_plugin
2828

29-
# Ignore errors in all parser-related files
30-
[mypy-pyquil._parser.*]
31-
ignore_errors = True
32-
3329
# Ignore errors in vendored third-party libraries
3430
[mypy-pyquil.external.*]
3531
ignore_errors = True

0 commit comments

Comments
 (0)