diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 00000000000..d8f4ea6dee1 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +/.github/stable/ @PennyLaneAI/Core diff --git a/.github/workflows/install_deps/action.yml b/.github/workflows/install_deps/action.yml new file mode 100644 index 00000000000..77ceb1389d3 --- /dev/null +++ b/.github/workflows/install_deps/action.yml @@ -0,0 +1,113 @@ +name: Install Dependencies +description: | + This workflow installs Python, PennyLane and all its dependencies. If a + requirements file is provided, it will upload the results of pip freeze + as well. +inputs: + python_version: + description: The version of Python to use in order to run unit tests + required: false + default: '3.9' + install_jax: + description: Indicate if JAX should be installed or not + required: false + default: 'true' + jax_version: + description: The version of JAX to install for any job that requires JAX + required: false + default: 0.4.23 + install_tensorflow: + description: Indicate if TensorFlow should be installed or not + required: false + default: 'true' + tensorflow_version: + description: The version of TensorFlow to install for any job that requires TensorFlow + required: false + default: 2.15.0 + install_pytorch: + description: Indicate if PyTorch should be installed or not + required: false + default: 'true' + pytorch_version: + description: The version of PyTorch to install for any job that requires PyTorch + required: false + default: 2.2.0 + install_pennylane_lightning_master: + description: Indicate if PennyLane-Lightning should be installed from the master branch + required: false + default: 'true' + additional_pip_packages: + description: Additional packages to install. Values will be passed to pip install {value} + required: false + default: '' + requirements_file: + description: File name to store stable version of requirements for a test group + required: false + default: '' + +runs: + using: composite + steps: + - name: Setup Python + uses: actions/setup-python@v4 + with: + python-version: '${{ inputs.python_version }}' + + - name: Upgrade PIP + shell: bash + run: pip install --upgrade pip && pip install wheel --upgrade + + - name: Install PennyLane dependencies + shell: bash + run: | + pip install -r requirements-ci.txt --upgrade + pip install -r requirements-dev.txt --upgrade + + - name: Install PyTorch + shell: bash + if: inputs.install_pytorch == 'true' + env: + TORCH_VERSION: ${{ inputs.pytorch_version != '' && format('=={0}', inputs.pytorch_version) || '' }} + run: pip install "torch${{ env.TORCH_VERSION }}" -f https://download.pytorch.org/whl/torch_stable.html + + - name: Install TensorFlow + shell: bash + if: inputs.install_tensorflow == 'true' + env: + TF_VERSION: ${{ inputs.tensorflow_version != '' && format('~={0}', inputs.tensorflow_version) || '' }} + run: pip install "tensorflow${{ env.TF_VERSION }}" "keras${{ env.TF_VERSION }}" + + - name: Install JAX + shell: bash + if: inputs.install_jax == 'true' + env: + JAX_VERSION: ${{ inputs.jax_version != '' && format('=={0}', inputs.jax_version) || '' }} + run: pip install "jax${{ env.JAX_VERSION}}" "jaxlib${{ env.JAX_VERSION }}" + + - name: Install additional PIP packages + shell: bash + if: inputs.additional_pip_packages != '' + run: pip install ${{ inputs.additional_pip_packages }} + + - name: Install PennyLane + shell: bash + run: | + python setup.py bdist_wheel + pip install dist/PennyLane*.whl + + - name: Install PennyLane-Lightning master + shell: bash + if: inputs.install_pennylane_lightning_master == 'true' + run: pip install -i https://test.pypi.org/simple/ PennyLane-Lightning --pre --upgrade + + - name: Freeze dependencies + shell: bash + if: inputs.requirements_file != '' + run: pip freeze | grep -v "file:///" > ${{ inputs.requirements_file }} + + - name: Upload frozen requirements + if: inputs.requirements_file != '' + uses: actions/upload-artifact@v4 + with: + name: frozen-${{ inputs.requirements_file }} + path: ${{ inputs.requirements_file }} diff --git a/.github/workflows/interface-unit-tests.yml b/.github/workflows/interface-unit-tests.yml index f94686642b7..2dfee7df77b 100644 --- a/.github/workflows/interface-unit-tests.yml +++ b/.github/workflows/interface-unit-tests.yml @@ -11,21 +11,6 @@ on: required: false type: string default: 'unit-tests' - jax_version: - description: The version of JAX to install for any job that requires JAX - required: false - type: string - default: 0.4.23 - tensorflow_version: - description: The version of TensorFlow to install for any job that requires TensorFlow - required: false - type: string - default: 2.15.0 - pytorch_version: - description: The version of PyTorch to install for any job that requires PyTorch - required: false - type: string - default: 2.2.0 pytest_coverage_flags: description: PyTest Coverage flags to pass to all jobs required: false @@ -162,10 +147,10 @@ jobs: install_jax: false install_tensorflow: false install_pytorch: true - pytorch_version: ${{ inputs.pytorch_version }} install_pennylane_lightning_master: true pytest_coverage_flags: ${{ inputs.pytest_coverage_flags }} pytest_markers: torch and not qcut and not finite-diff and not param-shift + requirements_file: ${{ strategy.job-index == 0 && 'torch.txt' || '' }} autograd-tests: @@ -225,13 +210,13 @@ jobs: pipeline_mode: ${{ inputs.pipeline_mode }} install_jax: false install_tensorflow: true - tensorflow_version: ${{ inputs.tensorflow_version }} install_pytorch: false install_pennylane_lightning_master: true pytest_coverage_flags: ${{ inputs.pytest_coverage_flags }} pytest_markers: tf and not qcut and not finite-diff and not param-shift pytest_additional_args: --splits 3 --group ${{ matrix.group }} --durations-path='.github/workflows/tf_tests_durations.json' additional_pip_packages: pytest-split + requirements_file: ${{ strategy.job-index == 0 && 'tf.txt' || '' }} jax-tests: @@ -259,7 +244,6 @@ jobs: python_version: ${{ matrix.python-version }} pipeline_mode: ${{ inputs.pipeline_mode }} install_jax: true - jax_version: ${{ inputs.jax_version }} install_tensorflow: false install_pytorch: false install_pennylane_lightning_master: true @@ -267,6 +251,7 @@ jobs: pytest_markers: jax and not qcut and not finite-diff and not param-shift pytest_additional_args: --splits 5 --group ${{ matrix.group }} --durations-path='.github/workflows/jax_tests_durations.json' additional_pip_packages: pytest-split + requirements_file: ${{ strategy.job-index == 0 && 'jax.txt' || '' }} core-tests: @@ -303,6 +288,7 @@ jobs: pytest_markers: core and not qcut and not finite-diff and not param-shift pytest_additional_args: --splits 2 --group ${{ matrix.group }} additional_pip_packages: pytest-split + requirements_file: ${{ strategy.job-index == 0 && 'core.txt' || '' }} all-interfaces-tests: @@ -329,14 +315,12 @@ jobs: python_version: ${{ matrix.python-version }} pipeline_mode: ${{ inputs.pipeline_mode }} install_jax: true - jax_version: ${{ inputs.jax_version }} install_tensorflow: true - tensorflow_version: ${{ inputs.tensorflow_version }} install_pytorch: true - pytorch_version: ${{ inputs.pytorch_version }} install_pennylane_lightning_master: false pytest_coverage_flags: ${{ inputs.pytest_coverage_flags }} pytest_markers: all_interfaces + requirements_file: ${{ strategy.job-index == 0 && 'all_interfaces.txt' || '' }} external-libraries-tests: @@ -363,14 +347,13 @@ jobs: python_version: ${{ matrix.python-version }} pipeline_mode: ${{ inputs.pipeline_mode }} install_jax: true - jax_version: ${{ inputs.jax_version }} install_tensorflow: true - tensorflow_version: ${{ inputs.tensorflow_version }} install_pytorch: false install_pennylane_lightning_master: false pytest_coverage_flags: ${{ inputs.pytest_coverage_flags }} pytest_markers: external - additional_pip_packages: git+https://github.com/Quantomatic/pyzx.git@master pennylane-catalyst matplotlib stim + additional_pip_packages: pyzx pennylane-catalyst matplotlib stim + requirements_file: ${{ strategy.job-index == 0 && 'external.txt' || '' }} qcut-tests: @@ -397,11 +380,8 @@ jobs: python_version: ${{ matrix.python-version }} pipeline_mode: ${{ inputs.pipeline_mode }} install_jax: true - jax_version: ${{ inputs.jax_version }} install_tensorflow: true - tensorflow_version: ${{ inputs.tensorflow_version }} install_pytorch: true - pytorch_version: ${{ inputs.pytorch_version }} install_pennylane_lightning_master: false pytest_coverage_flags: ${{ inputs.pytest_coverage_flags }} pytest_markers: qcut @@ -466,11 +446,8 @@ jobs: python_version: ${{ matrix.python-version }} pipeline_mode: ${{ inputs.pipeline_mode }} install_jax: true - jax_version: ${{ inputs.jax_version }} install_tensorflow: true - tensorflow_version: ${{ inputs.tensorflow_version }} install_pytorch: true - pytorch_version: ${{ inputs.pytorch_version }} install_pennylane_lightning_master: false pytest_coverage_flags: ${{ inputs.pytest_coverage_flags }} pytest_markers: ${{ matrix.config.suite }} @@ -543,11 +520,8 @@ jobs: python_version: ${{ matrix.python-version }} pipeline_mode: ${{ inputs.pipeline_mode }} install_jax: ${{ contains(matrix.config.device, 'jax') }} - jax_version: ${{ inputs.jax_version }} install_tensorflow: ${{ contains(matrix.config.device, 'tf') }} - tensorflow_version: ${{ inputs.tensorflow_version }} install_pytorch: ${{ contains(matrix.config.device, 'torch') }} - pytorch_version: ${{ inputs.pytorch_version }} install_pennylane_lightning_master: false pytest_test_directory: pennylane/devices/tests pytest_coverage_flags: ${{ inputs.pytest_coverage_flags }} diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 1108fe67a9c..9741f7224ee 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -9,6 +9,9 @@ concurrency: group: unit-tests-${{ github.ref }} cancel-in-progress: true +env: + DEPS_BRANCH: bot/stable-deps-update + jobs: tests: uses: ./.github/workflows/interface-unit-tests.yml @@ -24,3 +27,67 @@ jobs: && !contains(github.event.pull_request.labels.*.name, 'ci:run-full-test-suite') || false }} + + upload-stable-deps: + needs: tests + runs-on: ubuntu-latest + if: ${{ github.event_name == 'push' }} + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-tags: true + sparse-checkout: .github + + - name: Prepare local repo + 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 }}" + git rebase origin/master + else + git checkout master + git checkout -b "${{ env.DEPS_BRANCH }}" + fi + rm -f .github/stable/*.txt + + - name: Download artifacts + uses: actions/download-artifact@v4 + with: + pattern: frozen-* + path: .github/stable/ + merge-multiple: true + + - name: Determine if changes have been made + id: changed + run: | + echo "has_changes=$(git status --porcelain | wc -l | awk '{print $1}')" >> $GITHUB_OUTPUT + + - name: Stage changes + if: steps.changed.outputs.has_changes != '0' + run: | + git add .github/stable/ + git commit -m "Update changed dependencies" + git push -f --set-upstream origin "${{ env.DEPS_BRANCH }}" + + # Create PR to master + - name: Create pull request + if: steps.changed.outputs.has_changes != '0' + uses: repo-sync/pull-request@v2 + with: + source_branch: "${{ env.DEPS_BRANCH }}" + destination_branch: "master" + github_token: "${{ secrets.GITHUB_TOKEN }}" + pr_title: "Update stable dependency files" + pr_body: | + Automatic update of stable requirement files to snapshot valid python environments. + Because bots are not able to trigger CI on their own, please do so by pushing an empty commit to this branch using the following command: + + ``` + git commit --allow-empty -m 'trigger ci' + ``` + pr_allow_empty: false + pr_draft: false + pr_reviewer: "timmysilv" diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml index 3e6751f7d7f..c4d7d792764 100644 --- a/.github/workflows/unit-test.yml +++ b/.github/workflows/unit-test.yml @@ -89,6 +89,11 @@ on: required: false type: string default: '' + requirements_file: + description: File name to store stable version of requirements for a test group + required: false + type: string + default: '' jobs: test: @@ -128,53 +133,17 @@ jobs: || (inputs.pipeline_mode == 'reference-benchmarks' && steps.benchmark-cache.outputs.cache-hit != 'true' )}}" >> $GITHUB_OUTPUT - - name: Setup Python + - name: Install PennyLane and dependencies if: steps.continue.outputs.confirm == 'true' - uses: actions/setup-python@v4 + uses: ./.github/workflows/install_deps with: - python-version: '${{ inputs.python_version }}' - - - name: Upgrade PIP - if: steps.continue.outputs.confirm == 'true' - run: pip install --upgrade pip && pip install wheel --upgrade - - - name: Install PennyLane dependencies - if: steps.continue.outputs.confirm == 'true' - run: | - pip install -r requirements-ci.txt --upgrade - pip install -r requirements-dev.txt --upgrade - - - name: Install PyTorch - if: inputs.install_pytorch == true && steps.continue.outputs.confirm == 'true' - env: - TORCH_VERSION: ${{ inputs.pytorch_version != '' && format('=={0}', inputs.pytorch_version) || '' }} - run: pip install "torch${{ env.TORCH_VERSION }}" -f https://download.pytorch.org/whl/torch_stable.html - - - name: Install TensorFlow - if: inputs.install_tensorflow == true && steps.continue.outputs.confirm == 'true' - env: - TF_VERSION: ${{ inputs.tensorflow_version != '' && format('~={0}', inputs.tensorflow_version) || '' }} - run: pip install "tensorflow${{ env.TF_VERSION }}" "keras${{ env.TF_VERSION }}" - - - name: Install JAX - if: inputs.install_jax == true && steps.continue.outputs.confirm == 'true' - env: - JAX_VERSION: ${{ inputs.jax_version != '' && format('=={0}', inputs.jax_version) || '' }} - run: pip install "jax${{ env.JAX_VERSION}}" "jaxlib${{ env.JAX_VERSION }}" - - - name: Install additional PIP packages - if: inputs.additional_pip_packages != '' && steps.continue.outputs.confirm == 'true' - run: pip install ${{ inputs.additional_pip_packages }} - - - name: Install PennyLane - if: steps.continue.outputs.confirm == 'true' - run: | - python setup.py bdist_wheel - pip install dist/PennyLane*.whl - - - name: Install PennyLane-Lightning master - if: inputs.install_pennylane_lightning_master == true && steps.continue.outputs.confirm == 'true' - run: pip install -i https://test.pypi.org/simple/ PennyLane-Lightning --pre --upgrade + python_version: ${{ inputs.python_version }} + install_pytorch: ${{ inputs.install_pytorch }} + install_tensorflow: ${{ inputs.install_tensorflow }} + install_jax: ${{ inputs.install_jax }} + additional_pip_packages: ${{ inputs.additional_pip_packages }} + install_pennylane_lightning_master: ${{ inputs.install_pennylane_lightning_master }} + requirements_file: ${{ inputs.requirements_file }} - name: Set PyTest Args if: steps.continue.outputs.confirm == 'true'