From 3ba0bf9332eb3f2a0dc0841e54bd25d49da6eb7d Mon Sep 17 00:00:00 2001 From: Rakhim Davletkaliyev Date: Tue, 8 Nov 2022 11:43:19 +0200 Subject: [PATCH 01/12] Update README.md (#33) --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e5ebabe..796794f 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ backend = IQMBackend( url="https://cortex-demo.qc.iqm.fi", auth_server_url="https://auth.demo.qc.iqm.fi", username="USERNAME", - password="PASSWORD", + password="PASSWORD", ) circuit = Circuit(3, 3) @@ -63,6 +63,10 @@ by providing the `arch` parameter to the `IQMBackend` constructor, but it genera does not make sense, since the IQM server reports the valid quantum architecture relevant to the given backend URL. +(Note: At the moment IQM does not provide a quantum computing service open to the +general public. Please contact our [sales team](https://www.meetiqm.com/contact/) +to set up your access to an IQM quantum computer.) + ## Bugs and feature requests Please file bugs and feature requests on the GitHub From 67a85fa8b2dc310623000d9a28aeb77309daa28a Mon Sep 17 00:00:00 2001 From: cqc-melf <70640934+cqc-melf@users.noreply.github.com> Date: Mon, 21 Nov 2022 17:12:14 +0000 Subject: [PATCH 02/12] Update/ci jira 3 0 0 (#37) * Bump atlassian/gajira-login from 2.0.0 to 3.0.0 (#36) Bumps [atlassian/gajira-login](https://github.com/atlassian/gajira-login) from 2.0.0 to 3.0.0. - [Release notes](https://github.com/atlassian/gajira-login/releases) - [Commits](https://github.com/atlassian/gajira-login/compare/v2.0.0...v3.0.0) --- updated-dependencies: - dependency-name: atlassian/gajira-login dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump atlassian/gajira-create from 2.0.1 to 3.0.0 (#35) Bumps [atlassian/gajira-create](https://github.com/atlassian/gajira-create) from 2.0.1 to 3.0.0. - [Release notes](https://github.com/atlassian/gajira-create/releases) - [Commits](https://github.com/atlassian/gajira-create/compare/v2.0.1...v3.0.0) --- updated-dependencies: - dependency-name: atlassian/gajira-create dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/issue.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/issue.yml b/.github/workflows/issue.yml index 8731c09..55e7dd1 100644 --- a/.github/workflows/issue.yml +++ b/.github/workflows/issue.yml @@ -10,13 +10,13 @@ jobs: runs-on: ubuntu-22.04 steps: - name: Login - uses: atlassian/gajira-login@v2.0.0 + uses: atlassian/gajira-login@v3.0.0 env: JIRA_BASE_URL: ${{ secrets.JIRA_BASE_URL }} JIRA_USER_EMAIL: ${{ secrets.JIRA_USER_EMAIL }} JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }} - name: Create Bug - uses: atlassian/gajira-create@v2.0.1 + uses: atlassian/gajira-create@v3.0.0 if: contains(github.event.issue.labels.*.name, 'bug') with: project: TKET @@ -24,7 +24,7 @@ jobs: summary: « [pytket-iqm] ${{ github.event.issue.title }}» description: ${{ github.event.issue.html_url }} - name: Create Task - uses: atlassian/gajira-create@v2.0.1 + uses: atlassian/gajira-create@v3.0.0 if: "! contains(github.event.issue.labels.*.name, 'bug')" with: project: TKET From 23d563f41b5231554fc92c79c500d61a9a79dbbf Mon Sep 17 00:00:00 2001 From: cqc-melf <70640934+cqc-melf@users.noreply.github.com> Date: Thu, 24 Nov 2022 08:30:58 +0000 Subject: [PATCH 03/12] update tket version to pre release (#38) --- .github/workflows/build-test | 3 +++ .github/workflows/build_and_test.yml | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-test b/.github/workflows/build-test index 50f637e..7833968 100755 --- a/.github/workflows/build-test +++ b/.github/workflows/build-test @@ -51,6 +51,9 @@ cd ${GITHUB_WORKSPACE}/tests python -m pip install --pre -r test-requirements.txt +# update the pytket version to the lastest (pre) release +python -m pip install --upgrade --pre pytket~=1.0 + pytest --doctest-modules cd .. diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index b81deba..156b71c 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -9,6 +9,7 @@ on: branches: - develop - 'wheel/**' + - 'runci/**' release: types: - created @@ -35,7 +36,6 @@ jobs: fetch-depth: '0' - run: git fetch --depth=1 origin +refs/tags/*:refs/tags/* +refs/heads/*:refs/remotes/origin/* - name: Set up Python 3.9 - if: github.event_name == 'pull_request' || github.event_name == 'release' || contains(github.ref, 'refs/heads/wheel') || github.event_name == 'schedule' uses: actions/setup-python@v4 with: python-version: '3.9' @@ -46,7 +46,7 @@ jobs: env: PYTKET_RUN_REMOTE_TESTS: 1 - name: Build and test including remote checks (3.9) nomypy - if: (matrix.os != 'macos-12') && (github.event_name == 'pull_request' || github.event_name == 'release' || contains(github.ref, 'refs/heads/wheel') || github.event_name == 'schedule') + if: (matrix.os != 'macos-12') && (github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository) || github.event_name == 'release' || github.event_name == 'schedule') shell: bash run: | ./.github/workflows/build-test nomypy From d501dbdea61d16529f05d3be92425f8b4298b636 Mon Sep 17 00:00:00 2001 From: cqc-melf <70640934+cqc-melf@users.noreply.github.com> Date: Fri, 25 Nov 2022 11:05:52 +0000 Subject: [PATCH 04/12] update doc build to use github deployment (#39) * update doc build to use github deployment * add empty line add the end of the file --- .github/workflows/build_and_test.yml | 44 +++++++++++++++------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index 156b71c..862f0d1 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -98,8 +98,8 @@ jobs: password: ${{ secrets.PYPI_PYTKET_IQM_API_TOKEN }} verbose: true - docs: - name: Build and publish docs + build_docs: + name: Build docs if: github.event_name == 'release' needs: publish_to_pypi runs-on: ubuntu-22.04 @@ -117,7 +117,7 @@ jobs: path: wheelhouse - name: Install pip, wheel run: pip install -U pip wheel - - name: Install extensions + - name: Install extension run: for w in `find wheelhouse/ -type f -name "*.whl"` ; do pip install $w ; done - name: Install docs dependencies run: | @@ -127,20 +127,24 @@ jobs: run: | cd .github/workflows/docs mkdir extensions - ./build-docs -d ${GITHUB_WORKSPACE}/.github/workflows/docs/extensions - - name: Configure git - run: | - git config --global user.email "tket-bot@cambridgequantum.com" - git config --global user.name "«$GITHUB_WORKFLOW» github action" - - name: Check out gh-pages branch - run: git checkout gh-pages - - name: Remove old docs - run: git rm -r --ignore-unmatch docs/api - - name: Add generated docs to repository - run: | - mkdir -p docs - mv .github/workflows/docs/extensions docs/api - git add -f docs/api - git commit --allow-empty -m "Add generated documentation." - - name: Publish docs - run: git push origin gh-pages:gh-pages + ./build-docs -d ${GITHUB_WORKSPACE}/.github/workflows/docs/extensions/api + - name: Upload docs as artefact + uses: actions/upload-pages-artifact@v1 + with: + path: .github/workflows/docs/extensions + + publish_docs: + name: Publish docs + if: github.event_name == 'release' + needs: build_docs + runs-on: ubuntu-22.04 + permissions: + pages: write + id-token: write + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v1 From 5190c4e9b852f86312b168a80b0c933769e0bc4b Mon Sep 17 00:00:00 2001 From: cqc-melf <70640934+cqc-melf@users.noreply.github.com> Date: Tue, 20 Dec 2022 11:08:31 +0000 Subject: [PATCH 05/12] [infra] update gajira (#44) --- .github/workflows/issue.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/issue.yml b/.github/workflows/issue.yml index 55e7dd1..4798a2e 100644 --- a/.github/workflows/issue.yml +++ b/.github/workflows/issue.yml @@ -10,13 +10,13 @@ jobs: runs-on: ubuntu-22.04 steps: - name: Login - uses: atlassian/gajira-login@v3.0.0 + uses: atlassian/gajira-login@v3.0.1 env: JIRA_BASE_URL: ${{ secrets.JIRA_BASE_URL }} JIRA_USER_EMAIL: ${{ secrets.JIRA_USER_EMAIL }} JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }} - name: Create Bug - uses: atlassian/gajira-create@v3.0.0 + uses: atlassian/gajira-create@v3.0.1 if: contains(github.event.issue.labels.*.name, 'bug') with: project: TKET @@ -24,7 +24,7 @@ jobs: summary: « [pytket-iqm] ${{ github.event.issue.title }}» description: ${{ github.event.issue.html_url }} - name: Create Task - uses: atlassian/gajira-create@v3.0.0 + uses: atlassian/gajira-create@v3.0.1 if: "! contains(github.event.issue.labels.*.name, 'bug')" with: project: TKET From 106746cb6d9128396c705044a2dbdfa7e14ac653 Mon Sep 17 00:00:00 2001 From: cqc-melf <70640934+cqc-melf@users.noreply.github.com> Date: Fri, 6 Jan 2023 08:32:28 +0000 Subject: [PATCH 06/12] update copyright to 2023 (#45) --- pytket/extensions/iqm/__init__.py | 2 +- pytket/extensions/iqm/backends/__init__.py | 2 +- pytket/extensions/iqm/backends/config.py | 2 +- pytket/extensions/iqm/backends/iqm.py | 2 +- setup.py | 2 +- tests/backend_test.py | 2 +- tests/conftest.py | 2 +- tests/convert_test.py | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/pytket/extensions/iqm/__init__.py b/pytket/extensions/iqm/__init__.py index 41298d7..0e42819 100644 --- a/pytket/extensions/iqm/__init__.py +++ b/pytket/extensions/iqm/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2020-2022 Cambridge Quantum Computing +# Copyright 2020-2023 Cambridge Quantum Computing # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/pytket/extensions/iqm/backends/__init__.py b/pytket/extensions/iqm/backends/__init__.py index b48fa8f..32738f6 100644 --- a/pytket/extensions/iqm/backends/__init__.py +++ b/pytket/extensions/iqm/backends/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2020-2022 Cambridge Quantum Computing +# Copyright 2020-2023 Cambridge Quantum Computing # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/pytket/extensions/iqm/backends/config.py b/pytket/extensions/iqm/backends/config.py index 49d38e7..fb717b9 100644 --- a/pytket/extensions/iqm/backends/config.py +++ b/pytket/extensions/iqm/backends/config.py @@ -1,4 +1,4 @@ -# Copyright 2020-2022 Cambridge Quantum Computing +# Copyright 2020-2023 Cambridge Quantum Computing # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/pytket/extensions/iqm/backends/iqm.py b/pytket/extensions/iqm/backends/iqm.py index f379c47..a0f45ca 100644 --- a/pytket/extensions/iqm/backends/iqm.py +++ b/pytket/extensions/iqm/backends/iqm.py @@ -1,4 +1,4 @@ -# Copyright 2020-2022 Cambridge Quantum Computing +# Copyright 2020-2023 Cambridge Quantum Computing # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/setup.py b/setup.py index 7651772..25a88a0 100644 --- a/setup.py +++ b/setup.py @@ -1,4 +1,4 @@ -# Copyright 2020-2022 Cambridge Quantum Computing +# Copyright 2020-2023 Cambridge Quantum Computing # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/tests/backend_test.py b/tests/backend_test.py index 620a92d..88a4645 100644 --- a/tests/backend_test.py +++ b/tests/backend_test.py @@ -1,4 +1,4 @@ -# Copyright 2019-2022 Cambridge Quantum Computing +# Copyright 2019-2023 Cambridge Quantum Computing # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/tests/conftest.py b/tests/conftest.py index f91c8f7..bd1753b 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,4 +1,4 @@ -# Copyright 2020-2022 Cambridge Quantum Computing +# Copyright 2020-2023 Cambridge Quantum Computing # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/tests/convert_test.py b/tests/convert_test.py index 83543ab..806ef1d 100644 --- a/tests/convert_test.py +++ b/tests/convert_test.py @@ -1,4 +1,4 @@ -# Copyright 2020-2022 Cambridge Quantum Computing +# Copyright 2020-2023 Cambridge Quantum Computing # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. From 8363be517021d1ec2f814212261363acbc4044f4 Mon Sep 17 00:00:00 2001 From: cqc-melf <70640934+cqc-melf@users.noreply.github.com> Date: Tue, 17 Jan 2023 10:06:13 +0000 Subject: [PATCH 07/12] fix python version in docs build (#46) --- .github/workflows/docs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 6600ab1..15eff11 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -16,7 +16,7 @@ jobs: - name: Set up Python 3.9 uses: actions/setup-python@v4 with: - python-version: 3.9 + python-version: '3.9' - name: Upgrade pip and install wheel run: pip install --upgrade pip wheel - name: Install pytket iqm From 474a15e04bb9a86aa6691dc40eefdc4e91fc724e Mon Sep 17 00:00:00 2001 From: cqc-melf <70640934+cqc-melf@users.noreply.github.com> Date: Tue, 28 Feb 2023 16:06:40 +0000 Subject: [PATCH 08/12] update docbuild (#47) * update docbuild * update link to repo --- .github/workflows/docs/Quantinuum_logo.png | Bin 58430 -> 18245 bytes .github/workflows/docs/conf.py | 26 +++++++++--- .github/workflows/docs/requirements.txt | 3 +- .gitignore | 1 + docs/_static/custom.css | 44 +++++++++++++++++++++ 5 files changed, 68 insertions(+), 6 deletions(-) create mode 100644 docs/_static/custom.css diff --git a/.github/workflows/docs/Quantinuum_logo.png b/.github/workflows/docs/Quantinuum_logo.png index e15bc56f61301d93775a7d8543f01e69d43a7cf9..5569581b8e420f14eee561cbf1bf78ca0c96882f 100644 GIT binary patch literal 18245 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 diff --git a/.github/workflows/docs/conf.py b/.github/workflows/docs/conf.py index fe9a193..c44f60b 100644 --- a/.github/workflows/docs/conf.py +++ b/.github/workflows/docs/conf.py @@ -10,9 +10,24 @@ "sphinx.ext.autosummary", "sphinx.ext.intersphinx", "sphinx.ext.mathjax", + "sphinx_copybutton", ] -html_theme = "sphinx_rtd_theme" +pygments_style = "borland" + +html_theme = "sphinx_book_theme" + +html_theme_options = { + "repository_url": "https://github.com/CQCL/pytket-iqm", + "use_repository_button": True, + "use_issues_button": True, +} + +html_static_path = ["_static"] + +html_css_files = ["custom.css"] + +html_logo = "Quantinuum_logo.png" # -- Extension configuration ------------------------------------------------- @@ -29,13 +44,14 @@ # The following code is for resolving broken hyperlinks in the doc. -from sphinx.application import Sphinx +import re +from typing import Any, Dict, List, Optional +from urllib.parse import urljoin + from docutils import nodes from docutils.nodes import Element, TextElement +from sphinx.application import Sphinx from sphinx.environment import BuildEnvironment -from urllib.parse import urljoin -import re -from typing import Any, Dict, List, Optional # Mappings for broken hyperlinks that intersphinx cannot resolve external_url_mapping = { diff --git a/.github/workflows/docs/requirements.txt b/.github/workflows/docs/requirements.txt index 62096a9..31e9126 100644 --- a/.github/workflows/docs/requirements.txt +++ b/.github/workflows/docs/requirements.txt @@ -1,2 +1,3 @@ sphinx ~= 4.3.2 -sphinx_rtd_theme +sphinx_book_theme +sphinx-copybutton diff --git a/.gitignore b/.gitignore index 74ec74f..acc4832 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ build dist *.pyc .vscode +.venv .mypy_cache .hypothesis obj diff --git a/docs/_static/custom.css b/docs/_static/custom.css new file mode 100644 index 0000000..732d595 --- /dev/null +++ b/docs/_static/custom.css @@ -0,0 +1,44 @@ +.wy-side-nav-search, +.wy-nav-top { + background: #5A46BE; +} + +.wy-grid-for-nav, +.wy-body-for-nav, +.wy-nav-side, +.wy-side-scroll, +.wy-menu, +.wy-menu-vertical { + background-color: #FFFFFF; +} + +.wy-menu-vertical a:hover { + background-color: #d9d9d9; +} + +.caption-text { + color: #000000; +} + +.btn-link:visited, +.btn-link, +a:visited, +.a.reference.external, +.a.reference.internal, +.wy-menu-vertical a, +.wy-menu-vertical li, +.wy-menu-vertical ul, +.span.pre, +.sig-param, +.std.std-ref, +a { + color: #544d4d; +} + +:root { + --pst-color-inline-code: 199, 37, 78 !important; +} + +.sig-name { + font-size: 1.25rem; +} \ No newline at end of file From 0e3751ad60c7ed878888e47ce410eb77ac63d432 Mon Sep 17 00:00:00 2001 From: Alec Edgington <54802828+cqc-alec@users.noreply.github.com> Date: Tue, 28 Mar 2023 17:42:02 +0100 Subject: [PATCH 09/12] Feature/pr49 (#50) * Fix service URLs, update iqm-client * Fix mypy issues * Add method IQMBackend.get_metadata to read metadata of a completed job * Fix pylint issues --------- Co-authored-by: Olli Tyrkko --- .pylintrc | 2 - README.md | 6 +-- pytket/extensions/iqm/backends/iqm.py | 59 ++++++++++++++++++++--- setup.py | 2 +- tests/backend_test.py | 68 +++++++++++++++------------ tests/conftest.py | 19 +++++++- 6 files changed, 113 insertions(+), 43 deletions(-) diff --git a/.pylintrc b/.pylintrc index 6549ebb..7b25117 100644 --- a/.pylintrc +++ b/.pylintrc @@ -22,7 +22,6 @@ enable= line-too-long, lost-exception, missing-kwoa, - mixed-indentation, mixed-line-endings, not-callable, no-value-for-parameter, @@ -30,7 +29,6 @@ enable= not-in-loop, pointless-statement, redefined-builtin, - relative-import, return-arg-in-generator, return-in-init, return-outside-function, diff --git a/README.md b/README.md index 796794f..cb9fd6e 100644 --- a/README.md +++ b/README.md @@ -33,8 +33,8 @@ from pytket.extensions.iqm import IQMBackend from pytket.circuit import Circuit backend = IQMBackend( - url="https://cortex-demo.qc.iqm.fi", - auth_server_url="https://auth.demo.qc.iqm.fi", + url="https://demo.qc.iqm.fi/cocos", + auth_server_url="https://demo.qc.iqm.fi/auth", username="USERNAME", password="PASSWORD", ) @@ -126,7 +126,7 @@ skipped. To enable them, set the following environment variables: ```shell export PYTKET_RUN_REMOTE_TESTS=1 -export PYTKET_REMOTE_IQM_AUTH_SERVER_URL=https://auth.demo.qc.iqm.fi +export PYTKET_REMOTE_IQM_AUTH_SERVER_URL=https://demo.qc.iqm.fi/auth export PYTKET_REMOTE_IQM_USERNAME=YOUR_USERNAME export PYTKET_REMOTE_IQM_PASSWORD=YOUR_PASSWORD ``` diff --git a/pytket/extensions/iqm/backends/iqm.py b/pytket/extensions/iqm/backends/iqm.py index a0f45ca..2c818a6 100644 --- a/pytket/extensions/iqm/backends/iqm.py +++ b/pytket/extensions/iqm/backends/iqm.py @@ -13,12 +13,13 @@ # limitations under the License. import json -from typing import cast, Dict, List, Optional, Sequence, Union +from typing import cast, Dict, List, Optional, Sequence, Tuple, Union from uuid import UUID from iqm_client.iqm_client import Circuit as IQMCircuit from iqm_client.iqm_client import ( Instruction, IQMClient, + Metadata, ) import numpy as np from pytket.backends import Backend, CircuitStatus, ResultHandle, StatusEnum @@ -221,7 +222,9 @@ def process_circuits( instrs = _translate_iqm(c0) qm = {str(qb): _as_name(qb) for qb in c.qubits} iqmc = IQMCircuit( - name=c.name if c.name else f"circuit_{i}", instructions=instrs + name=c.name if c.name else f"circuit_{i}", + instructions=instrs, + metadata=None, ) run_id = self._client.submit_circuits( [iqmc], qubit_mapping=qm, shots=n_shots @@ -285,6 +288,39 @@ def get_result(self, handle: ResultHandle, **kwargs: KwargTypes) -> BackendResul assert circuit_status.status is StatusEnum.ERROR raise RuntimeError(circuit_status.message) + def get_metadata(self, handle: ResultHandle, **kwargs: KwargTypes) -> Metadata: + """Return the metadata corresponding to the handle. + + Use keyword arguments to specify parameters to be used in retrieving + the metadata. + + * `timeout`: maximum time to wait for remote job to finish + + Example usage: + n_shots = 100 + backend.run_circuit(circuit, n_shots=n_shots, timeout=30) + handle = backend.process_circuits([circuit], n_shots=n_shots)[0] + result = backend.get_result(handle) + metadata = backend.get_metadata(handle) + print([qm.physical_name for qm in metadata.request.qubit_mapping]) + + :param handle: handle to results + :type handle: ResultHandle + :return: Metadata corresponding to handle + :rtype: Metadata + """ + self._check_handle_type(handle) + if handle in self._cache and "metadata" in self._cache[handle]: + return cast(Metadata, self._cache[handle]["metadata"]) + # Wait for job to finish, capture metadata and store it in cache + timeout = kwargs.get("timeout", 900) + run_id = UUID(bytes=cast(bytes, handle[0])) + run_result = self._client.wait_for_results( + run_id, timeout_secs=cast(float, timeout) + ) + self._cache[handle]["metadata"] = run_result.metadata + return cast(Metadata, self._cache[handle]["metadata"]) + def _as_node(qname: str) -> Node: assert qname.startswith("QB") @@ -298,7 +334,7 @@ def _as_name(qnode: Node) -> str: return f"QB{qnode.index[0] + 1}" -def _translate_iqm(circ: Circuit) -> List[Instruction]: +def _translate_iqm(circ: Circuit) -> Tuple[Instruction, ...]: """Convert a circuit in the IQM gate set to IQM list representation.""" instrs = [] for cmd in circ.get_commands(): @@ -310,18 +346,27 @@ def _translate_iqm(circ: Circuit) -> List[Instruction]: if optype == OpType.PhasedX: instr = Instruction( name="phased_rx", - qubits=[str(qbs[0])], + implementation=None, + qubits=(str(qbs[0]),), args={"angle_t": 0.5 * params[0], "phase_t": 0.5 * params[1]}, ) elif optype == OpType.CZ: - instr = Instruction(name="cz", qubits=[str(qbs[0]), str(qbs[1])], args={}) + instr = Instruction( + name="cz", + implementation=None, + qubits=(str(qbs[0]), str(qbs[1])), + args={}, + ) else: assert optype == OpType.Measure instr = Instruction( - name="measurement", qubits=[str(qbs[0])], args={"key": str(cbs[0])} + name="measurement", + implementation=None, + qubits=(str(qbs[0]),), + args={"key": str(cbs[0])}, ) instrs.append(instr) - return instrs + return tuple(instrs) def _iqm_rebase() -> BasePass: diff --git a/setup.py b/setup.py index 25a88a0..9c78458 100644 --- a/setup.py +++ b/setup.py @@ -42,7 +42,7 @@ license="Apache 2", packages=find_namespace_packages(include=["pytket.*"]), include_package_data=True, - install_requires=["pytket ~= 1.8", "iqm-client ~= 9.1"], + install_requires=["pytket ~= 1.8", "iqm-client ~= 11.7"], classifiers=[ "Environment :: Console", "Programming Language :: Python :: 3.9", diff --git a/tests/backend_test.py b/tests/backend_test.py index 88a4645..ce37ee0 100644 --- a/tests/backend_test.py +++ b/tests/backend_test.py @@ -13,10 +13,11 @@ # limitations under the License. import os +from uuid import UUID import pytest from requests import get from conftest import get_demo_url # type: ignore -from iqm_client.iqm_client import ClientAuthenticationError +from iqm_client.iqm_client import ClientAuthenticationError, Metadata, RunRequest from pytket.circuit import Circuit # type: ignore from pytket.backends import StatusEnum from pytket.extensions.iqm import IQMBackend @@ -32,20 +33,10 @@ @pytest.mark.skipif(skip_remote_tests, reason=REASON) -def test_iqm(authenticated_iqm_backend: IQMBackend) -> None: +def test_iqm(authenticated_iqm_backend: IQMBackend, sample_circuit: Circuit) -> None: # Run a circuit on the demo device. b = authenticated_iqm_backend - c = Circuit(4, 4) - c.H(0) - c.CX(0, 1) - c.Rz(0.3, 2) - c.CSWAP(0, 1, 2) - c.CRz(0.4, 2, 3) - c.CY(1, 3) - c.ZZPhase(0.1, 2, 0) - c.Tdg(3) - c.measure_all() - c = b.get_compiled_circuit(c) + c = b.get_compiled_circuit(sample_circuit) n_shots = 10 res = b.run_circuit(c, n_shots=n_shots, timeout=30) shots = res.get_shots() @@ -54,24 +45,23 @@ def test_iqm(authenticated_iqm_backend: IQMBackend) -> None: assert sum(counts.values()) == n_shots +@pytest.mark.skipif(skip_remote_tests, reason=REASON) def test_invalid_cred(demo_url: str) -> None: with pytest.raises(ClientAuthenticationError): _ = IQMBackend( url=demo_url, - auth_server_url="https://auth.demo.qc.iqm.fi", + auth_server_url="https://demo.qc.iqm.fi/auth", username="invalid", password="invalid", ) @pytest.mark.skipif(skip_remote_tests, reason=REASON) -def test_handles(authenticated_iqm_backend: IQMBackend) -> None: +def test_handles( + authenticated_iqm_backend: IQMBackend, sample_circuit: Circuit +) -> None: b = authenticated_iqm_backend - c = Circuit(2, 2) - c.H(0) - c.CX(0, 1) - c.measure_all() - c = b.get_compiled_circuit(c) + c = b.get_compiled_circuit(sample_circuit) n_shots = 5 res = b.run_circuit(c, n_shots=n_shots, timeout=30) shots = res.get_shots() @@ -89,20 +79,40 @@ def test_handles(authenticated_iqm_backend: IQMBackend) -> None: for handle in handles: assert b.circuit_status(handle).status == StatusEnum.COMPLETED for result in results: - assert result.get_shots().shape == (n_shots, 2) + assert result.get_shots().shape == (n_shots, c.n_qubits) @pytest.mark.skipif(skip_remote_tests, reason=REASON) -def test_none_nshots(authenticated_iqm_backend: IQMBackend) -> None: +def test_metadata( + authenticated_iqm_backend: IQMBackend, sample_circuit: Circuit +) -> None: b = authenticated_iqm_backend - c = Circuit(2, 2) - c.H(0) - c.CX(0, 1) - c.measure_all() - c = b.get_compiled_circuit(c) - with pytest.raises(ValueError) as errorinfo: + c = b.get_compiled_circuit(sample_circuit) + n_shots = 5 + b.run_circuit(c, n_shots=n_shots, timeout=30) + handle = b.process_circuits([c], n_shots=n_shots)[0] + b.get_result(handle) + metadata = b.get_metadata(handle) + assert isinstance(metadata, Metadata) + assert isinstance(metadata.calibration_set_id, UUID) + assert isinstance(metadata.request, RunRequest) + assert len(metadata.request.circuits) == 1 + assert metadata.request.circuits[0].name == c.name + assert metadata.request.calibration_set_id is None + assert isinstance(metadata.request.qubit_mapping, list) + assert len(metadata.request.qubit_mapping) == c.n_qubits + assert metadata.request.shots == n_shots + + +@pytest.mark.skipif(skip_remote_tests, reason=REASON) +def test_none_nshots( + authenticated_iqm_backend: IQMBackend, sample_circuit: Circuit +) -> None: + b = authenticated_iqm_backend + c = b.get_compiled_circuit(sample_circuit) + with pytest.raises(ValueError) as error_info: _ = b.process_circuits([c]) - assert "Parameter n_shots is required" in str(errorinfo.value) + assert "Parameter n_shots is required" in str(error_info.value) @pytest.mark.skipif(skip_remote_tests, reason=REASON) diff --git a/tests/conftest.py b/tests/conftest.py index bd1753b..f5d9ddf 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -15,10 +15,11 @@ import os import pytest from pytket.extensions.iqm import IQMBackend +from pytket.circuit import Circuit def get_demo_url() -> str: - return "https://cortex-demo.qc.iqm.fi/" + return "https://demo.qc.iqm.fi/cocos" @pytest.fixture(name="demo_url", scope="session") @@ -40,3 +41,19 @@ def fixture_authenticated_iqm_backend() -> IQMBackend: username=os.getenv("PYTKET_REMOTE_IQM_USERNAME"), password=os.getenv("PYTKET_REMOTE_IQM_PASSWORD"), ) + + +@pytest.fixture(name="sample_circuit", scope="session") +def fixture_sample_circuit() -> Circuit: + c = Circuit(4, 4) + c.H(0) + c.CX(0, 1) + c.Rz(0.3, 2) + c.CSWAP(0, 1, 2) + c.CRz(0.4, 2, 3) + c.CY(1, 3) + c.ZZPhase(0.1, 2, 0) + c.Tdg(3) + c.measure_all() + c.name = "test_circuit" + return c From 8fad303863c70f32ee05e5bff69f2e9f24b24677 Mon Sep 17 00:00:00 2001 From: Alec Edgington Date: Wed, 29 Mar 2023 13:39:27 +0100 Subject: [PATCH 10/12] Update requirements. --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 9c78458..4c636aa 100644 --- a/setup.py +++ b/setup.py @@ -42,7 +42,7 @@ license="Apache 2", packages=find_namespace_packages(include=["pytket.*"]), include_package_data=True, - install_requires=["pytket ~= 1.8", "iqm-client ~= 11.7"], + install_requires=["pytket ~= 1.13", "iqm-client ~= 11.8"], classifiers=[ "Environment :: Console", "Programming Language :: Python :: 3.9", From a351e133d5762e4530e13c096b959da3e367a1b5 Mon Sep 17 00:00:00 2001 From: Alec Edgington Date: Wed, 29 Mar 2023 13:41:59 +0100 Subject: [PATCH 11/12] Update version and changelog. --- _metadata.py | 2 +- docs/changelog.rst | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/_metadata.py b/_metadata.py index 3284371..be52f94 100644 --- a/_metadata.py +++ b/_metadata.py @@ -1,2 +1,2 @@ -__extension_version__ = "0.5.0" +__extension_version__ = "0.6.0" __extension_name__ = "pytket-iqm" diff --git a/docs/changelog.rst b/docs/changelog.rst index 4854a54..76d224f 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -1,6 +1,12 @@ Changelog ~~~~~~~~~ +0.6.0 (March 2023) +------------------ + +* Updated pytket version requirement to 1.13. +* Updated iqm-client version requirement to 11.8. + 0.5.0 (November 2022) --------------------- From c5bdada8e60a9b598883935c64b685dca65d15c0 Mon Sep 17 00:00:00 2001 From: Alec Edgington Date: Wed, 29 Mar 2023 14:28:21 +0100 Subject: [PATCH 12/12] Update changelog. --- docs/changelog.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/changelog.rst b/docs/changelog.rst index 76d224f..987a58f 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -6,6 +6,8 @@ Changelog * Updated pytket version requirement to 1.13. * Updated iqm-client version requirement to 11.8. +* New method ``IQMBackend.get_metadata()`` for reteieving metadata associated + with a ``ResultHandle``. 0.5.0 (November 2022) ---------------------