Skip to content

Commit

Permalink
Merge branch 'master' into readme-update
Browse files Browse the repository at this point in the history
  • Loading branch information
justinpickering authored Nov 8, 2024
2 parents 31ee87a + 03440b7 commit 7e433d2
Show file tree
Hide file tree
Showing 37 changed files with 939 additions and 185 deletions.
49 changes: 31 additions & 18 deletions .github/workflows/check_in_artifact.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,29 +56,39 @@ on:
required: false
type: string
default: '41898282+github-actions[bot]@users.noreply.github.com'
merge_multiple:
description: |
When multiple artifacts are matched, this changes the behavior of the destination directories.
If true, the downloaded artifacts will be in the same directory specified by path.
If false, the downloaded artifacts will be extracted into individual named directories within the specified path.
Optional. Default is 'true'
required: false
type: boolean
default: true

jobs:
check_in_artifact:
runs-on: ubuntu-latest

steps:
- name: Checkout master
uses: actions/checkout@v4
with:
fetch-depth: ${{ inputs.master_branch_fetch_depth }}
ref: master

- name: Download artifacts
uses: actions/download-artifact@v4
with:
pattern: ${{ inputs.artifact_name_pattern }}
path: ${{ inputs.artifact_save_path }}

merge-multiple: ${{ inputs.merge_multiple }}

- name: Determine if changes have been made
id: changed
run: |
echo "has_changes=$(git status --porcelain | wc -l | awk '{print $1}')" >> $GITHUB_OUTPUT
- name: Prepare Commit Author
if: steps.changed.outputs.has_changes != '0'
env:
Expand All @@ -88,7 +98,8 @@ jobs:
run: |
git config user.name "$COMMIT_AUTHOR_NAME"
git config user.email "$COMMIT_AUTHOR_EMAIL"
git stash push --all
echo "Checking if $HEAD_BRANCH_NAME exists..."
if git ls-remote --exit-code origin "refs/heads/$HEAD_BRANCH_NAME"; then
echo "$HEAD_BRANCH_NAME exists! Checking out..."
Expand All @@ -97,17 +108,18 @@ jobs:
echo "$HEAD_BRANCH_NAME does not exist! Creating..."
git checkout -b "$HEAD_BRANCH_NAME"
fi
- name: Stage changes
if: steps.changed.outputs.has_changes != '0'
env:
HEAD_BRANCH_NAME: ${{ inputs.pull_request_head_branch_name }}
COMMIT_MESSAGE_DESCRIPTION: ${{ inputs.commit_message_description != '' && format('-> {0}', inputs.commit_message_description) || '' }}
run: |
git checkout stash -- .
git add ${{ inputs.artifact_save_path }}
git commit -m "Check in artifacts$COMMIT_MESSAGE_DESCRIPTION"
git commit --allow-empty -m "Check in artifacts$COMMIT_MESSAGE_DESCRIPTION"
git push -f --set-upstream origin "$HEAD_BRANCH_NAME"
# Create PR to master
- name: Create Pull Request to master
if: steps.changed.outputs.has_changes != '0'
Expand All @@ -117,20 +129,21 @@ jobs:
PR_TITLE: ${{ inputs.pull_request_title }}
PR_BODY: ${{ inputs.pull_request_body }}
run: |
EXISTING_CLOSED_PR="$(gh pr list --state closed --base master --head $HEAD_BRANCH_NAME --json url --jq '.[].url')"
if [ -n "${EXISTING_CLOSED_PR}" ]; then
echo "Reopening PR... ${EXISTING_CLOSED_PR}"
gh pr reopen "${EXISTING_CLOSED_PR}"
exit 0
fi
EXISTING_PR="$(gh pr list --state open --base master --head $HEAD_BRANCH_NAME --json url --jq '.[].url')"
EXISTING_PR="$(gh pr list --state open --base master --head $HEAD_BRANCH_NAME --json 'url' --jq '.[].url' | head -n 1)"
if [ -n "${EXISTING_PR}" ]; then
echo "PR already exists ==> ${EXISTING_PR}"
exit 0
else
echo "Creating PR..."
gh pr create --title "$PR_TITLE" --body "$PR_BODY"
exit 0
fi
EXISTING_CLOSED_PR="$(gh pr list --state closed --base master --head $HEAD_BRANCH_NAME --json 'mergedAt,url' --jq '.[] | select(.mergedAt == null).url' | head -n 1)"
if [ -n "${EXISTING_CLOSED_PR}" ]; then
echo "Reopening PR... ${EXISTING_CLOSED_PR}"
gh pr reopen "${EXISTING_CLOSED_PR}"
exit 0
fi
64 changes: 24 additions & 40 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,6 @@ jobs:

sphinx:
if: github.event.pull_request.draft == false
env:
DEPS_BRANCH: bot/stable-deps-update
needs: [determine_runner]
runs-on: ${{ needs.determine_runner.outputs.runner_group }}
steps:
Expand All @@ -50,46 +48,32 @@ jobs:
&& pip3 install .
&& pip3 install openfermionpyscf
&& pip3 install aiohttp fsspec h5py
&& pip freeze | grep -v 'file:///' > .github/stable/doc.txt.tmp
build-command: "sphinx-build -b html . _build -W --keep-going"

- name: Prepare local repo
if: github.event.pull_request.head.repo.full_name == 'PennyLaneAI/pennylane'
- name: Freeze dependencies
shell: bash
run: |
git fetch
git config user.name "GitHub Actions Bot"
git config user.email "<>"
if git ls-remote --exit-code origin "refs/heads/${{ env.DEPS_BRANCH }}"; then
git checkout "${{ env.DEPS_BRANCH }}"
else
git checkout master
git pull
git checkout -b "${{ env.DEPS_BRANCH }}"
fi
mv -f .github/stable/doc.txt.tmp .github/stable/doc.txt
pip freeze | grep -v 'file:///' > doc.txt
cat doc.txt
- name: Determine if changes have been made
if: github.event.pull_request.head.repo.full_name == 'PennyLaneAI/pennylane'
id: changed
run: |
echo "has_changes=$(git status --porcelain | wc -l | awk '{print $1}')" >> $GITHUB_OUTPUT
- name: Stage changes
if: github.event.pull_request.head.repo.full_name == 'PennyLaneAI/pennylane' && steps.changed.outputs.has_changes != '0'
run: |
git add .github/stable/doc.txt
git commit -m "Update stable docs dependencies"
git push -f --set-upstream origin "${{ env.DEPS_BRANCH }}"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Upload frozen requirements
uses: actions/upload-artifact@v4
with:
name: frozen-doc
path: doc.txt

# Create PR to master
- name: Create pull request
if: github.event.pull_request.head.repo.full_name == 'PennyLaneAI/pennylane' && steps.changed.outputs.has_changes != '0'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
function gh_pr_up() {
gh pr create $* || gh pr edit $*
}
gh_pr_up --title \"Update stable doc dependency files\" --body \".\"
upload-stable-deps:
if: github.event.pull_request.draft == false
needs:
- determine_runner
- sphinx
uses: ./.github/workflows/check_in_artifact.yml
with:
artifact_name_pattern: "frozen-doc"
artifact_save_path: ".github/stable/"
merge_multiple: true
pull_request_head_branch_name: bot/stable-deps-update
commit_message_description: Frozen Doc Dependencies Update
pull_request_title: Update stable dependency files
pull_request_body: |
Automatic update of stable requirement files to snapshot valid python environments.
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ jobs:
upload-stable-deps:
needs: tests
uses: ./.github/workflows/check_in_artifact.yml
if: github.event_name == 'push'
if: github.event_name == 'schedule'
with:
artifact_name_pattern: "frozen-*"
artifact_save_path: ".github/stable/"
Expand Down
Binary file added doc/_static/draw_mpl/per_wire_options.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/_static/tape_mpl/per_wire_options.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion doc/code/qml_drawer.rst
Original file line number Diff line number Diff line change
Expand Up @@ -85,4 +85,4 @@ Currently Available Styles
+|pls|+|plw|+|skd|+
+-----+-----+-----+
+|sol|+|sod|+|def|+
+-----+-----+-----+
+-----+-----+-----+
4 changes: 2 additions & 2 deletions doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@

intersphinx_mapping = {
"demo": ("https://pennylane.ai/qml/", None),
"catalyst": ("https://docs.pennylane.ai/projects/catalyst/en/stable", None)
"catalyst": ("https://docs.pennylane.ai/projects/catalyst/en/stable", None),
}

mathjax_path = (
Expand Down Expand Up @@ -113,6 +113,7 @@
# built documents.

import pennylane

pennylane.Hamiltonian = pennylane.ops.Hamiltonian

# The full version, including alpha/beta/rc tags.
Expand Down Expand Up @@ -254,7 +255,6 @@

# Xanadu theme options (see theme.conf for more information).
html_theme_options = {
"navbar_active_link": 4,
"extra_copyrights": [
"TensorFlow, the TensorFlow logo, and any related marks are trademarks " "of Google Inc."
],
Expand Down
11 changes: 11 additions & 0 deletions doc/introduction/interfaces.rst
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,17 @@ a :class:`QNode <pennylane.QNode>`, e.g.,
If no interface is specified, PennyLane will automatically determine the interface based on provided arguments and keyword arguments.
See ``qml.workflow.SUPPORTED_INTERFACES`` for a list of all accepted interface strings.

.. warning::

``ComplexWarning`` messages may appear when running differentiable workflows involving both complex and float types, particularly
with certain interfaces. These warnings are common in backpropagation due to the nature of complex casting and do not
indicate an error in computation. If desired, you can suppress these warnings by adding the following code:

.. code-block:: python
import warnings
warnings.filterwarnings("ignore", category=np.ComplexWarning)
This will allow native numerical objects of the specified library (NumPy arrays, JAX arrays, Torch Tensors,
or TensorFlow Tensors) to be passed as parameters to the quantum circuit. It also makes
the gradients of the quantum circuit accessible to the classical library, enabling the
Expand Down
47 changes: 33 additions & 14 deletions doc/releases/changelog-dev.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# Release 0.40.0-dev (development release)

<h3>New features since last release</h3>

* A `DeviceCapabilities` data class is defined to contain all capabilities of the device's execution interface (i.e. its implementation of `Device.execute`). A TOML file can be used to define the capabilities of a device, and it can be loaded into a `DeviceCapabilities` object.
[(#6407)](https://github.com/PennyLaneAI/pennylane/pull/6407)

Expand All @@ -15,21 +15,30 @@
True
```

<h4>New API for Qubit Mixed</h4>

* Added `qml.devices.qubit_mixed` module for mixed-state qubit device support. This module introduces:

[(#6379)](https://github.com/PennyLaneAI/pennylane/pull/6379) An `apply_operation` helper function featuring:

* Two density matrix contraction methods using `einsum` and `tensordot`

* Optimized handling of special cases including: Diagonal operators, Identity operators, CX (controlled-X), Multi-controlled X gates, Grover operators

[(#6503)](https://github.com/PennyLaneAI/pennylane/pull/6503) A submodule 'initialize_state' featuring a `create_initial_state` function for initializing a density matrix from `qml.StatePrep` operations or `qml.QubitDensityMatrix` operations

<h3>Improvements 🛠</h3>

<h4>Other Improvements</h4>
* Added support for the `wire_options` dictionary to customize wire line formatting in `qml.draw_mpl` circuit
visualizations, allowing global and per-wire customization with options like `color`, `linestyle`, and `linewidth`.
[(#6486)](https://github.com/PennyLaneAI/pennylane/pull/6486)

* Added `qml.devices.qubit_mixed` module for mixed-state qubit device support. This module introduces:
- A new API for mixed-state operations
- An `apply_operation` helper function featuring:
- Two density matrix contraction methods using `einsum` and `tensordot`
- Optimized handling of special cases including:
- Diagonal operators
- Identity operators
- CX (controlled-X)
- Multi-controlled X gates
- Grover operators
[(#6379)](https://github.com/PennyLaneAI/pennylane/pull/6379)
<h4>Capturing and representing hybrid programs</h4>

* `jax.vmap` can be captured with `qml.capture.make_plxpr` and is compatible with quantum circuits.
[(#6349)](https://github.com/PennyLaneAI/pennylane/pull/6349)

<h4>Other Improvements</h4>

* `qml.BasisRotation` template is now JIT compatible.
[(#6019)](https://github.com/PennyLaneAI/pennylane/pull/6019)
Expand All @@ -43,11 +52,21 @@

<h3>Documentation 📝</h3>

* Add a warning message to Gradients and training documentation about ComplexWarnings
[(#6543)](https://github.com/PennyLaneAI/pennylane/pull/6543)

<h3>Bug fixes 🐛</h3>

* Fixed `Identity.__repr__` to return correct wires list.
[(#6506)](https://github.com/PennyLaneAI/pennylane/pull/6506)

<h3>Contributors ✍️</h3>

This release contains contributions from (in alphabetical order):

Shiwen An
Astral Cai,
Andrija Paurevic
Yushao Chen,
Pietropaolo Frisoni,
Andrija Paurevic,
Justin Pickering
2 changes: 1 addition & 1 deletion pennylane/_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@
Version number (major.minor.patch[-label])
"""

__version__ = "0.40.0-dev8"
__version__ = "0.40.0-dev9"
27 changes: 15 additions & 12 deletions pennylane/capture/capture_diff.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,28 +25,31 @@


@lru_cache
def create_non_jvp_primitive():
"""Create a primitive type ``NonJVPPrimitive``, which binds to JAX's JVPTrace
like a standard Python function and otherwise behaves like jax.core.Primitive.
def create_non_interpreted_prim():
"""Create a primitive type ``NonInterpPrimitive``, which binds to JAX's JVPTrace
and BatchTrace objects like a standard Python function and otherwise behaves like jax.core.Primitive.
"""

if not has_jax: # pragma: no cover
return None

# pylint: disable=too-few-public-methods
class NonJVPPrimitive(jax.core.Primitive):
class NonInterpPrimitive(jax.core.Primitive):
"""A subclass to JAX's Primitive that works like a Python function
when evaluating JVPTracers."""
when evaluating JVPTracers and BatchTracers."""

def bind_with_trace(self, trace, args, params):
"""Bind the ``NonJVPPrimitive`` with a trace. If the trace is a ``JVPTrace``,
binding falls back to a standard Python function call. Otherwise, the
bind call of JAX's standard Primitive is used."""
if isinstance(trace, jax.interpreters.ad.JVPTrace):
"""Bind the ``NonInterpPrimitive`` with a trace.
If the trace is a ``JVPTrace``or a ``BatchTrace``, binding falls back to a standard Python function call.
Otherwise, the bind call of JAX's standard Primitive is used."""
if isinstance(
trace, (jax.interpreters.ad.JVPTrace, jax.interpreters.batching.BatchTrace)
):
return self.impl(*args, **params)
return super().bind_with_trace(trace, args, params)

return NonJVPPrimitive
return NonInterpPrimitive


@lru_cache
Expand All @@ -57,7 +60,7 @@ def _get_grad_prim():
if not has_jax: # pragma: no cover
return None

grad_prim = create_non_jvp_primitive()("grad")
grad_prim = create_non_interpreted_prim()("grad")
grad_prim.multiple_results = True # pylint: disable=attribute-defined-outside-init

# pylint: disable=too-many-arguments
Expand Down Expand Up @@ -89,7 +92,7 @@ def _get_jacobian_prim():
"""Create a primitive for Jacobian computations.
This primitive is used when capturing ``qml.jacobian``.
"""
jacobian_prim = create_non_jvp_primitive()("jacobian")
jacobian_prim = create_non_interpreted_prim()("jacobian")
jacobian_prim.multiple_results = True # pylint: disable=attribute-defined-outside-init

# pylint: disable=too-many-arguments
Expand Down
Loading

0 comments on commit 7e433d2

Please sign in to comment.