-
Notifications
You must be signed in to change notification settings - Fork 57
Merge v0.13.0-rc back into main #2124
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
… 1 (#2090) **Context:** Dynamic one-shot execution causes a crash or yields incorrect output when we set `shots=1`. (See related issues #2087 and #2088 for details). This issue was caused by an oversight when using the function `jnp.squeeze`. When `shots=1`, the code removes the first axis of the output array, which corresponds to the number of shots. This interferes with subsequent calculations and leads to the crashes and incorrect results as mentioned. **Description of the Change:** This change modifies the output handling to correctly preserve the shots dimension in the case when `shots=1`. closes #2087 #2088 [[sc-100800]] [[sc-100803]] --------- Co-authored-by: Isaac De Vlugt <[email protected]> Co-authored-by: Ali Asadi <[email protected]> Co-authored-by: ringo-but-quantum <[email protected]> Co-authored-by: Paul <[email protected]>
Rename the`t_layer_reduction` transform to `reduce_t_depth` for more user-friendly [[sc-99454]]
… parameters (#2099) **Context:** Fix the issue with compiling decomposition_rules with flatten list of parameters ``` python qml.capture.enable() qml.decomposition.enable_graph() @qjit(target="mlir") @partial(qml.transforms.decompose, gate_set=[qml.RX, qml.RY, qml.RZ]) @qml.qnode(qml.device(backend, wires=2)) def captured_circuit(x: float, y: float, z: float): qml.Rot(x, y, z, 0) return qml.expval(qml.PauliZ(0)) capture_result = captured_circuit(1.5, 2.5, 3.5) qml.decomposition.disable_graph() qml.capture.disable() print(captured_circuit.mlir) ``` Compiles the Rot decomp rule to: ``` llvm func.func public @_rot_to_rz_ry_rz(%arg0: !quantum.reg, %arg1: tensor<f64>, %arg2: tensor<f64>, %arg3: tensor<f64>, %arg4: tensor<1xi64>) -> !quantum.reg attributes {llvm.linkage = #llvm.linkage<internal>, num_wires = 1 : i64, target_gate = "Rot"} { %0 = stablehlo.slice %arg4 [0:1] : (tensor<1xi64>) -> tensor<1xi64> %1 = stablehlo.reshape %0 : (tensor<1xi64>) -> tensor<i64> %extracted = tensor.extract %1[] : tensor<i64> %2 = quantum.extract %arg0[%extracted] : !quantum.reg -> !quantum.bit %extracted_0 = tensor.extract %arg2[] : tensor<f64> %out_qubits = quantum.custom "RZ"(%extracted_0) %2 : !quantum.bit %3 = stablehlo.slice %arg4 [0:1] : (tensor<1xi64>) -> tensor<1xi64> %4 = stablehlo.reshape %3 : (tensor<1xi64>) -> tensor<i64> %extracted_1 = tensor.extract %1[] : tensor<i64> %5 = quantum.insert %arg0[%extracted_1], %out_qubits : !quantum.reg, !quantum.bit %extracted_2 = tensor.extract %4[] : tensor<i64> %6 = quantum.extract %5[%extracted_2] : !quantum.reg -> !quantum.bit %extracted_3 = tensor.extract %arg3[] : tensor<f64> %out_qubits_4 = quantum.custom "RY"(%extracted_3) %6 : !quantum.bit %7 = stablehlo.slice %arg4 [0:1] : (tensor<1xi64>) -> tensor<1xi64> %8 = stablehlo.reshape %7 : (tensor<1xi64>) -> tensor<i64> %extracted_5 = tensor.extract %4[] : tensor<i64> %9 = quantum.insert %5[%extracted_5], %out_qubits_4 : !quantum.reg, !quantum.bit %extracted_6 = tensor.extract %8[] : tensor<i64> %10 = quantum.extract %9[%extracted_6] : !quantum.reg -> !quantum.bit %extracted_7 = tensor.extract %arg1[] : tensor<f64> %out_qubits_8 = quantum.custom "RZ"(%extracted_7) %10 : !quantum.bit %extracted_9 = tensor.extract %8[] : tensor<i64> %11 = quantum.insert %9[%extracted_9], %out_qubits_8 : !quantum.reg, !quantum.bit return %11 : !quantum.reg } ``` The results in a decomposition function RZ RY RZ with the params order: param1, param2, param 0 instead of params arg0 (param 0), arg1 (param 1) and arg2 (param 2). The issue is coming from the fact that JAX Tracer doesn't preserve the order of keyword arguments passed from Python in the partial initialization of rules. We are now passing arguments as 'unnamed' but ordered args. ``` llvm func.func public @_rot_to_rz_ry_rz(%arg0: !quantum.reg, %arg1: tensor<f64>, %arg2: tensor<f64>, %arg3: tensor<f64>, %arg4: tensor<1xi64>) -> !quantum.reg attributes {llvm.linkage = #llvm.linkage<internal>, num_wires = 1 : i64, target_gate = "Rot"} { %0 = stablehlo.slice %arg4 [0:1] : (tensor<1xi64>) -> tensor<1xi64> %1 = stablehlo.reshape %0 : (tensor<1xi64>) -> tensor<i64> %extracted = tensor.extract %1[] : tensor<i64> %2 = quantum.extract %arg0[%extracted] : !quantum.reg -> !quantum.bit %extracted_0 = tensor.extract %arg1[] : tensor<f64> %out_qubits = quantum.custom "RZ"(%extracted_0) %2 : !quantum.bit %3 = stablehlo.slice %arg4 [0:1] : (tensor<1xi64>) -> tensor<1xi64> %4 = stablehlo.reshape %3 : (tensor<1xi64>) -> tensor<i64> %extracted_1 = tensor.extract %1[] : tensor<i64> %5 = quantum.insert %arg0[%extracted_1], %out_qubits : !quantum.reg, !quantum.bit %extracted_2 = tensor.extract %4[] : tensor<i64> %6 = quantum.extract %5[%extracted_2] : !quantum.reg -> !quantum.bit %extracted_3 = tensor.extract %arg2[] : tensor<f64> %out_qubits_4 = quantum.custom "RY"(%extracted_3) %6 : !quantum.bit %7 = stablehlo.slice %arg4 [0:1] : (tensor<1xi64>) -> tensor<1xi64> %8 = stablehlo.reshape %7 : (tensor<1xi64>) -> tensor<i64> %extracted_5 = tensor.extract %4[] : tensor<i64> %9 = quantum.insert %5[%extracted_5], %out_qubits_4 : !quantum.reg, !quantum.bit %extracted_6 = tensor.extract %8[] : tensor<i64> %10 = quantum.extract %9[%extracted_6] : !quantum.reg -> !quantum.bit %extracted_7 = tensor.extract %arg3[] : tensor<f64> %out_qubits_8 = quantum.custom "RZ"(%extracted_7) %10 : !quantum.bit %extracted_9 = tensor.extract %8[] : tensor<i64> %11 = quantum.insert %9[%extracted_9], %out_qubits_8 : !quantum.reg, !quantum.bit return %11 : !quantum.reg } ``` **Benefits:** - Decomposition works with flatten params end-to-end **Possible Drawbacks:** **Related GitHub Issues:** [sc-100937]
**Context:** PRs targeting `v0.13.0-rc` should be tested with the release candidate branches of PL and Lightning as well. We manually overwrite the CI to install these directly after `make frontend` (which gets the version from `.dep_versions`). Note that when merging rc branch back to main after the release, this PR must be reverted for `.dep_versions` to take back control of the versions.
The implementation simply wraps user provided functions in parameter-less wrappers that propagate user-provided arguments via closure. A special case is maintained from a earlier bugfix in #1232 that allowed "standard" usage of qml.cond with gate constructor without matching the return types across branches, by dropping the return value in the single operator case. closes #2086 supersedes #1531 and #1232
…2101) **Context:** Change check-catalyst (CI on PRs in catalyst repo targeting the rc branch) to use rc PennyLane from testpypi instead of git.
**Context:**
Fix qml.prod with autograph
```python
@qml.prod
def template(b):
if b:
qml.H(0)
qml.X(0)
@qjit(autograph=True)
@qml.qnode(qml.device("null.qubit", wires=1))
def circuit(b: bool):
template(b)
return qml.state()
print(circuit(True))
```
Error message:
```
jax.errors.TracerBoolConversionError: Attempted boolean conversion of traced array with shape bool[].
The error occurred while tracing the function circuit at ... for qjit_capture. This concrete value was not available in Python because it depends on the value of the argument b.
See https://docs.jax.dev/en/latest/errors.html#jax.errors.TracerBoolConversionError
```
**Description of the Change:**
HOTFIX: Handle calls to functions that were decorated with qml.prod,
qml.adjoint, etc. These decorators return wrapper functions that call
the original function without autograph conversion. We detect these
wrappers and unwrap them to convert the original function with
autograph.
TODO: Once PL has has dedicated way to propagate autograph through
decorators, we should remove this way of handling `qml.prod`.
**Benefits:**
**Possible Drawbacks:**
**Related GitHub Issues:**
[sc-95653]
#1911
---------
Co-authored-by: David Ittah <[email protected]>
**Context:** Kokkos tests in CI need to install base lightning package as well. --------- Co-authored-by: Joseph Lee <[email protected]> Co-authored-by: Ali Asadi <[email protected]>
**Context:** There are some error cases where we should issue a better, more actionable error message regarding the dynamic allocation feature. **Description of the Change:** Add specific error messages for the following error cases: - Using dynamic allocation without program capture - Implicit wires in terminal MP - Dynamically allocated wires in terminal MP - Use-after-free - Subroutines **Benefits:** Better error message. **Related GitHub Issues:** closes #2071 [sc-100475]
Do not fallback to QubitUnitary unless operator provides no decomposition. Previously, a QubitUnitary would be constructed for any Controlled operator not natively supported by the device. While this can have some advantages, e.g. better performance on simulators for gates up to a certain size (which was never the intention of the fallback), it can also cause issues like overly large constant matrices embedded into the IR, and can also be unexpected to users since they might expect a decomposition to elementary gates. The proposed update should be more robust in that it still uses the QubitUnitary fallback for gates that don't implement a decomposition, but otherwise makes use of the provided one. closes #2077
**Context:** We don't run codefactor on rc branch. This causes some codefactor complaints on the autosync from rc branch to main branch every day (e.g. the final manual commits I added in #2108). Next release I will enable codefactor on rc branch. This time around, it's already Thursday so I'll just sync it manually.
**Context:** **Description of the Change:** Added traversal logic of mcm. For an example, finding the `qreg` and index of `qb3` in the following case, it needs to traverse the def-use chain through the ops. ``` qb0 = extract(...) ... meas_result, qb2 = qml.measure(qb1, 0) ... qb4 = op(qb3, ...) ``` **Refactoring** 1. Use `QuantumGate` to traverse the gates instead of `CustomOp` 2. Collect qreg and qubit index with only one walk **Benefits:** **Possible Drawbacks:** **Related GitHub Issues:** [sc-100311] --------- Co-authored-by: Paul <[email protected]> Co-authored-by: Mehrdad Malek <[email protected]> Co-authored-by: ringo-but-quantum <[email protected]> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Jeffrey Kam <[email protected]> Co-authored-by: Isaac De Vlugt <[email protected]> Co-authored-by: Ali Asadi <[email protected]> Co-authored-by: paul0403 <[email protected]>
**Description of the Change:** Updated conditional checks to ensure correct handling of measurement changes during QNode transformations. **Related GitHub Issues:** Closes #2070 --------- Co-authored-by: Hong-Sheng Zheng <[email protected]>
**Context:** When using mid circuit measurements `catalyst.measure()`
and passing its value into a measurement process under the
single-branch-statistics mode, it fails with a low level error
concerning LLVM translation, which is not helpful to the user.
```
import catalyst
import pennylane as qml
@qml.qjit
@qml.set_shots(10)
@qml.qnode(qml.device("lightning.qubit", wires=2))
def c():
qml.H(0)
m = catalyst.measure(0)
return qml.expval(m)
c()
```
Running the above program gives the following error.
```
CompileError: catalyst failed with error code 1: Compilation failed:
c:27:12: error: LLVM Translation failed for operation: builtin.unrealized_conversion_cast
%9 = "quantum.compbasis"(%8) {operandSegmentSizes = array<i32: 0, 1>} : (!quantum.reg) -> !quantum.obs
^
c:27:12: note: see current operation: %20 = "builtin.unrealized_conversion_cast"() : () -> i64
Failed to translate LLVM module
```
**Description of the Change:**
Added some validation checks earlier to capture and raise the
appropriate error during the tracing stage.
**Benefits:** A more informative error message to let users know the
cause of failure.
[[sc-97982]]
WORK IN PROGRESS **Context:** Nanobind reports reference leaks in certain CIs. This turns out to be caused by global caching of qnodes, even when they are no longer needed. **Description of the Change:** 1. Updates the dynamic one-shot transform to no longer take the entire qnode as a global variable 2. Removes the cache within the `Function` class which would gradually accumulate objects since it is no longer needed **Benefits:** Prevents Python objects from remaining in memory after they are no longer needed **Possible Drawbacks:** **Related GitHub Issues:** [sc-99563] --------- Co-authored-by: Paul <[email protected]> Co-authored-by: Mehrdad Malek <[email protected]> Co-authored-by: ringo-but-quantum <[email protected]> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Jeffrey Kam <[email protected]> Co-authored-by: Isaac De Vlugt <[email protected]> Co-authored-by: Ali Asadi <[email protected]> Co-authored-by: paul0403 <[email protected]> Co-authored-by: Sengthai Heng <[email protected]> Co-authored-by: David Ittah <[email protected]>
**Context:** Various small OQC fixes. **Description of the Change:** - The error message when account info is missing now includes the env variables to set - OQC cpp device itself should not be the one starting the python interpreter (this will cause python's "cannot start multiple interpreters" error from user python script). Instead, whatever cpp tests that need this should start their python interpreter with pybind. - update to new OQC API - Properly link up the backend to use, instead of always falling back to lucy - Migrate to new shots scheme (shots goes with qnode, not the device) **Benefits:** OQC device works **Related GitHub Issues:** #2021 [sc-98652]
**Context:** Insertion of qubits to qreg is missing after the PR: https://github.com/PennyLaneAI/catalyst/pull/2068/files **Description of the Change:** Restore the change TODO: - [x] Add integration test **Benefits:** **Possible Drawbacks:** **Related GitHub Issues:** --------- Co-authored-by: Ali Asadi <[email protected]>
v0.13.0 changelog edits [sc-98522](https://app.shortcut.com/xanaduai/story/98522/catalyst-changelog) --------- Co-authored-by: Paul <[email protected]> Co-authored-by: AntonNI8 <[email protected]> Co-authored-by: David Ittah <[email protected]>
**Context:** Pylint released 4.0.0 yesterday and broke CI. To not interfere with release, we pin Pylint to the previous working version 3.3.9.
…2118) **Context:** Bump the PennyLane and Lightning minimum versions in preparation for the Catalyst 0.13.0 release. These changes ensure we can build the wheels after the Lightning release and before the core PennyLane release.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Context:
Merge v0.13.0-rc back into main.