Skip to content
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

Release/1.22 #214

Merged
merged 18 commits into from
Nov 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,12 @@ updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
interval: "daily"
- package-ecosystem: pip
directory: "/"
schedule:
interval: "daily"
groups:
python-packages:
patterns:
- "*"
14 changes: 10 additions & 4 deletions .github/workflows/docs/build-docs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,11 @@ from pathlib import Path

DOCS_DIR = Path(sys.argv[0]).absolute().parent
MODULES_DIR = DOCS_DIR.parent.parent.parent
PYTKET_DOCS_LINK = "https://cqcl.github.io/tket/pytket/api/index.html"
PYTKET_EX_DOCS_LINK = "https://cqcl.github.io/pytket-extensions/api/index.html"
TKET_EXAMPLES_LINK = "https://tket.quantinuum.com/examples/"
TKET_MANUAL_LINK = "https://tket.quantinuum.com/user-manual/"
TKET_WEBSITE_LINK = "https://tket.quantinuum.com/"
PYTKET_DOCS_LINK = "https://tket.quantinuum.com/api-docs/"
PYTKET_EX_DOCS_LINK = "https://tket.quantinuum.com/api-docs/extensions.html"
PYTKET_QISKIT_PYPI_LINK = "https://pypi.org/project/pytket-qiskit/"
PYTKET_QISKIT_GITHUB = "https://github.com/CQCL/pytket-qiskit"
MODULE = "qiskit"
Expand Down Expand Up @@ -50,10 +53,13 @@ def build_module_docs():
with open(mod_docs / "intro.txt", "r") as f:
content = f.readlines()
content.append(
"\n.. toctree::\n\t:caption: More documentation:\n\t:maxdepth: 1\n\n"
"\n.. toctree::\n\t:caption: pytket documentation:\n\t:maxdepth: 1\n\n"
)
content.append(f"\tpytket <{PYTKET_DOCS_LINK}>\n")
content.append(f"\tpytket API docs <{PYTKET_DOCS_LINK}>\n")
content.append(f"\tpytket extensions <{PYTKET_EX_DOCS_LINK}>\n")
content.append(f"\tManual <{TKET_MANUAL_LINK}>\n")
content.append(f"\tExample notebooks <{TKET_EXAMPLES_LINK}>\n")
content.append(f"\tTKET website <{TKET_WEBSITE_LINK}>\n")
content.append("\n.. toctree::\n\t:caption: Links:\n\t:maxdepth: 1\n\n")
content.append(f"\tbug tracker <{PYTKET_QISKIT_GITHUB}/issues>\n")
content.append(f"\tGitHub <{PYTKET_QISKIT_GITHUB}>\n")
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@

# -- Extension configuration -------------------------------------------------

pytketdoc_base = "https://cqcl.github.io/tket/pytket/api/"
pytketdoc_base = "https://tket.quantinuum.com/api-docs/"

intersphinx_mapping = {
"https://docs.python.org/3/": None,
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ obj
docs/extensions
.ipynb_checkpoints
pytket/extensions/qiskit/_metadata.py
*.ipynb
13 changes: 5 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
# Pytket Extensions

This repository contains the pytket-qiskit extension, using Quantinuum's
[pytket](https://cqcl.github.io/tket/pytket/api/index.html) quantum SDK.

# pytket-qiskit

[Pytket](https://cqcl.github.io/tket/pytket/api/index.html) is a python module for interfacing
with tket, a quantum computing toolkit and optimisation compiler developed by Quantinuum.
[Pytket](https://tket.quantinuum.com/api-docs/index.html) is a python module for interfacing
with tket, a quantum computing toolkit and optimising compiler developed by Quantinuum.

`pytket-qiskit` is an extension to `pytket` that allows `pytket` circuits to be
run on IBM backends and simulators, as well as conversion to and from Qiskit
Expand All @@ -17,7 +12,9 @@ representations.
`pytket-qiskit` is available for Python 3.9, 3.10 and 3.11, on Linux, MacOS
and Windows. To install, run:

```pip install pytket-qiskit```
```shell
pip install pytket-qiskit
```

This will install `pytket` if it isn't already installed, and add new classes
and methods into the `pytket.extensions` namespace.
Expand Down
2 changes: 1 addition & 1 deletion _metadata.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
__extension_version__ = "0.45.0"
__extension_version__ = "0.46.0"
__extension_name__ = "pytket-qiskit"
16 changes: 15 additions & 1 deletion docs/changelog.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,20 @@
Changelog
~~~~~~~~~

0.46.0 (November 2023)
----------------------

* Updated pytket version requirement to 1.22.
* Add support for circuits with barriers in the Aer simulators.
* Update qiskit version to 0.45.0.
* Update qiskit-ibm-runtime version to 0.15.1.
* Update qiskit-aer version to 0.13.0.
* Update qiskit-ibm-provider version to 0.7.2.
* Introduce dependency on qiskit-algorithms.
* Seed given to ``process_circuits()`` will be automatically incremented
for the different circuit batches submitted.
* Fix :py:class:`RuntimeError` caused by the use of custom gates in ``qiskit_to_tk`` `#200 <https://github.com/CQCL/pytket-qiskit/issues/200>`_.

0.45.0 (October 2023)
---------------------

Expand Down Expand Up @@ -43,7 +57,7 @@ Changelog
0.40.0 (June 2023)
------------------

* IBM devices are now accessed using the `qiskit-ibm-provider <https://github.com/Qiskit/qiskit-ibm-provider>`_ instead of the deprecated :py:class:`IBMQ`. This allows the newest IBM devices and simulators to be accessed through ``pytket-qiskit``. See the updated documentation on `credentials <https://cqcl.github.io/pytket-qiskit/api/index.html#access-and-credentials>`_.
* IBM devices are now accessed using the `qiskit-ibm-provider <https://github.com/Qiskit/qiskit-ibm-provider>`_ instead of the deprecated :py:class:`IBMQ`. This allows the newest IBM devices and simulators to be accessed through ``pytket-qiskit``. See the updated documentation on `credentials <https://tket.quantinuum.com/extensions/pytket-qiskit/api/index.html#access-and-credentials>`_.
* The parameters ``hub``, ``group`` and ``project`` are no longer handled as separate arguments in :py:class:`IBMQBackend` and :py:meth:`IBMQBackend.available_devices`. Use ``"instance=f"{hub}/{group}/{project}"`` instead.
* Added support for the {X, SX, Rz, ECR} in the default compilation pass for :py:class:`IBMQBackend` and :py:class:`IBMQEmulatorBackend`. This is the set of gates used by some of the new IBM devices.
* Fix to the :py:meth:`tk_to_qiskit` converter to prevent cancellation of redundant gates when converting to qiskit.
Expand Down
60 changes: 30 additions & 30 deletions docs/intro.txt
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ To see which devices you can access you can use the ``available_devices`` method

my_instance=f"{hub}/{group}/{project}"
ibm_provider = IBMProvider(instance=my_instance)
backend = IBMQBackend("ibmq_belem") # Initialise backend for an IBM device
backend = IBMQBackend("ibmq_nairobi") # Initialise backend for an IBM device
backendinfo_list = backend.available_devices(instance=my_instance, provider=ibm_provider)
print([backend.device_name for backend in backendinfo_list])

Expand All @@ -122,15 +122,15 @@ and several types of simulator.

* - Backend
- Type
* - `IBMQBackend <https://cqcl.github.io/pytket-qiskit/api/api.html#pytket.extensions.qiskit.IBMQBackend>`_
* - `IBMQBackend <https://tket.quantinuum.com/extensions/pytket-qiskit/api/api.html#pytket.extensions.qiskit.IBMQBackend>`_
- Interface to an IBM quantum computer.
* - `IBMQEmulatorBackend <https://cqcl.github.io/pytket-qiskit/api/api.html#pytket.extensions.qiskit.IBMQEmulatorBackend>`_
* - `IBMQEmulatorBackend <https://tket.quantinuum.com/extensions/pytket-qiskit/api/api.html#pytket.extensions.qiskit.IBMQEmulatorBackend>`_
- Emulator for a chosen ``IBMBackend`` (Device specific).
* - `AerBackend <https://cqcl.github.io/pytket-qiskit/api/api.html#pytket.extensions.qiskit.AerBackend>`_
* - `AerBackend <https://tket.quantinuum.com/extensions/pytket-qiskit/api/api.html#pytket.extensions.qiskit.AerBackend>`_
- A noiseless, shots-based simulator for quantum circuits [1]
* - `AerStateBackend <https://cqcl.github.io/pytket-qiskit/api/api.html#pytket.extensions.qiskit.AerStateBackend>`_
* - `AerStateBackend <https://tket.quantinuum.com/extensions/pytket-qiskit/api/api.html#pytket.extensions.qiskit.AerStateBackend>`_
- Statevector simulator.
* - `AerUnitaryBackend <https://cqcl.github.io/pytket-qiskit/api/api.html#pytket.extensions.qiskit.AerUnitaryBackend>`_
* - `AerUnitaryBackend <https://tket.quantinuum.com/extensions/pytket-qiskit/api/api.html#pytket.extensions.qiskit.AerUnitaryBackend>`_
- Unitary simulator

* [1] :py:class:`AerBackend` is noiseless by default and has no architecture. However it can accept a user defined :py:class:`NoiseModel` and :py:class:`Architecture`.
Expand All @@ -148,37 +148,37 @@ Every :py:class:`Backend` in pytket has its own ``default_compilation_pass`` met
* - optimisation_level = 0
- optimisation_level = 1
- optimisation_level = 2 [1]
* - `DecomposeBoxes <https://cqcl.github.io/tket/pytket/api/passes.html#pytket.passes.DecomposeBoxes>`_
- `DecomposeBoxes <https://cqcl.github.io/tket/pytket/api/passes.html#pytket.passes.DecomposeBoxes>`_
- `DecomposeBoxes <https://cqcl.github.io/tket/pytket/api/passes.html#pytket.passes.DecomposeBoxes>`_
* - `DecomposeBoxes <https://tket.quantinuum.com/api-docs/passes.html#pytket.passes.DecomposeBoxes>`_
- `DecomposeBoxes <https://tket.quantinuum.com/api-docs/passes.html#pytket.passes.DecomposeBoxes>`_
- `DecomposeBoxes <https://tket.quantinuum.com/api-docs/passes.html#pytket.passes.DecomposeBoxes>`_
* - self.rebase_pass [2]
- `SynthesiseTket <https://cqcl.github.io/tket/pytket/api/passes.html#pytket.passes.SynthesiseTket>`_
- `FullPeepholeOptimise <https://cqcl.github.io/tket/pytket/api/passes.html#pytket.passes.FullPeepholeOptimise>`_
* - `CXMappingPass <https://cqcl.github.io/tket/pytket/api/passes.html#pytket.passes.CXMappingPass>`_ [3]
- `CXMappingPass <https://cqcl.github.io/tket/pytket/api/passes.html#pytket.passes.CXMappingPass>`_ [3]
- `CXMappingPass <https://cqcl.github.io/tket/pytket/api/passes.html#pytket.passes.CXMappingPass>`_ [3]
* - `NaivePlacementPass <https://cqcl.github.io/tket/pytket/api/placement.html#pytket.passes.NaivePlacementPass>`_
- `NaivePlacementPass <https://cqcl.github.io/tket/pytket/api/placement.html#pytket.passes.NaivePlacementPass>`_
- `NaivePlacementPass <https://cqcl.github.io/tket/pytket/api/placement.html#pytket.passes.NaivePlacementPass>`_
- `SynthesiseTket <https://tket.quantinuum.com/api-docs/passes.html#pytket.passes.SynthesiseTket>`_
- `FullPeepholeOptimise <https://tket.quantinuum.com/api-docs/passes.html#pytket.passes.FullPeepholeOptimise>`_
* - `CXMappingPass <https://tket.quantinuum.com/api-docs/passes.html#pytket.passes.CXMappingPass>`_ [3]
- `CXMappingPass <https://tket.quantinuum.com/api-docs/passes.html#pytket.passes.CXMappingPass>`_ [3]
- `CXMappingPass <https://tket.quantinuum.com/api-docs/passes.html#pytket.passes.CXMappingPass>`_ [3]
* - `NaivePlacementPass <https://tket.quantinuum.com/api-docs/placement.html#pytket.passes.NaivePlacementPass>`_
- `NaivePlacementPass <https://tket.quantinuum.com/api-docs/placement.html#pytket.passes.NaivePlacementPass>`_
- `NaivePlacementPass <https://tket.quantinuum.com/api-docs/placement.html#pytket.passes.NaivePlacementPass>`_
* - self.rebase_pass [2]
- `SynthesiseTket <https://cqcl.github.io/tket/pytket/api/passes.html#pytket.passes.SynthesiseTket>`_
- `KAKDecomposition(allow_swaps=False) <https://cqcl.github.io/tket/pytket/api/passes.html#pytket.passes.KAKDecomposition>`_
* - `RemoveRedundancies <https://cqcl.github.io/tket/pytket/api/passes.html#pytket.passes.RemoveRedundancies>`_
- `SynthesiseTket <https://tket.quantinuum.com/api-docs/passes.html#pytket.passes.SynthesiseTket>`_
- `KAKDecomposition(allow_swaps=False) <https://tket.quantinuum.com/api-docs/passes.html#pytket.passes.KAKDecomposition>`_
* - `RemoveRedundancies <https://tket.quantinuum.com/api-docs/passes.html#pytket.passes.RemoveRedundancies>`_
- self.rebase_pass [2]
- `CliffordSimp(allow_swaps=False) <https://cqcl.github.io/tket/pytket/api/passes.html#pytket.passes.CliffordSimp>`_
- `CliffordSimp(allow_swaps=False) <https://tket.quantinuum.com/api-docs/passes.html#pytket.passes.CliffordSimp>`_
* -
- `RemoveRedundancies <https://cqcl.github.io/tket/pytket/api/passes.html#pytket.passes.RemoveRedundancies>`_
- `SynthesiseTket <https://cqcl.github.io/tket/pytket/api/passes.html#pytket.passes.SynthesiseTket>`_
- `RemoveRedundancies <https://tket.quantinuum.com/api-docs/passes.html#pytket.passes.RemoveRedundancies>`_
- `SynthesiseTket <https://tket.quantinuum.com/api-docs/passes.html#pytket.passes.SynthesiseTket>`_
* -
-
- self.rebase_pass [2]
* -
-
- `RemoveRedundancies <https://cqcl.github.io/tket/pytket/api/passes.html#pytket.passes.RemoveRedundancies>`_
- `RemoveRedundancies <https://tket.quantinuum.com/api-docs/passes.html#pytket.passes.RemoveRedundancies>`_

* [1] If no value is specified then ``optimisation_level`` defaults to a value of 2.
* [2] self.rebase_pass is a rebase to the gateset supported by the backend, For IBM quantum devices that is {X, SX, Rz, CX}.
* [3] Here :py:class:`CXMappingPass` maps program qubits to the architecture using a `NoiseAwarePlacement <https://cqcl.github.io/tket/pytket/api/placement.html#pytket.placement.NoiseAwarePlacement>`_
* [3] Here :py:class:`CXMappingPass` maps program qubits to the architecture using a `NoiseAwarePlacement <https://tket.quantinuum.com/api-docs/placement.html#pytket.placement.NoiseAwarePlacement>`_


**Note:** The ``default_compilation_pass`` for :py:class:`AerBackend` is the same as above.
Expand All @@ -191,14 +191,14 @@ Circuits must satisfy certain conditions before they can be processed on a devic

All ``pytket-qiskit`` backends have the following two predicates.

* `GateSetPredicate <https://cqcl.github.io/tket/pytket/api/predicates.html#pytket.predicates.GateSetPredicate>`_ - The circuit must contain only operations supported by the :py:class`Backend`. To view supported Ops run ``BACKENDNAME.backend_info.gate_set``.
* `NoSymbolsPredicate <https://cqcl.github.io/tket/pytket/api/predicates.html#pytket.predicates.NoSymbolsPredicate>`_ - Parameterised gates must have numerical values when the circuit is executed.
* `GateSetPredicate <https://tket.quantinuum.com/api-docs/predicates.html#pytket.predicates.GateSetPredicate>`_ - The circuit must contain only operations supported by the :py:class`Backend`. To view supported Ops run ``BACKENDNAME.backend_info.gate_set``.
* `NoSymbolsPredicate <https://tket.quantinuum.com/api-docs/predicates.html#pytket.predicates.NoSymbolsPredicate>`_ - Parameterised gates must have numerical values when the circuit is executed.

The :py:class:`IBMQBackend` and :py:class:`IBMQEmulatorBackend` may also have the following predicates depending on the capabilities of the specified device.

* `NoClassicalControlPredicate <https://cqcl.github.io/tket/pytket/api/predicates.html#pytket.predicates.NoClassicalControlPredicate>`_
* `NoMidMeasurePredicate <https://cqcl.github.io/tket/pytket/api/predicates.html#pytket.predicates.NoMidMeasurePredicatePredicate>`_
* `NoFastFeedforwardPredicate <https://cqcl.github.io/tket/pytket/api/predicates.html#pytket.predicates.NoFastFeedforwardPredicate>`_
* `NoClassicalControlPredicate <https://tket.quantinuum.com/api-docs/predicates.html#pytket.predicates.NoClassicalControlPredicate>`_
* `NoMidMeasurePredicate <https://tket.quantinuum.com/api-docs/predicates.html#pytket.predicates.NoMidMeasurePredicatePredicate>`_
* `NoFastFeedforwardPredicate <https://tket.quantinuum.com/api-docs/predicates.html#pytket.predicates.NoFastFeedforwardPredicate>`_

.. toctree::
api.rst
Expand Down
18 changes: 13 additions & 5 deletions pytket/extensions/qiskit/backends/aer.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,15 +99,17 @@ def _tket_gate_set_from_qiskit_backend(
for gate_str in config.basis_gates
if gate_str in _gate_str_2_optype
}

gate_set.add(OpType.Barrier)

if "unitary" in config.basis_gates:
gate_set.add(OpType.Unitary1qBox)
gate_set.add(OpType.Unitary2qBox)
gate_set.add(OpType.Unitary3qBox)

if qiskit_backend.name() != "aer_simulator_unitary":
gate_set.add(OpType.Reset)
gate_set.add(OpType.Measure)
gate_set.add(OpType.Conditional)
gate_set.add(OpType.Reset)
gate_set.add(OpType.Measure)
gate_set.add(OpType.Conditional)

# special case mapping TK1 to U
gate_set.add(OpType.TK1)
Expand Down Expand Up @@ -237,6 +239,10 @@ def process_circuits(
valid_check: bool = True,
**kwargs: KwargTypes,
) -> List[ResultHandle]:
"""
See :py:meth:`pytket.backends.Backend.process_circuits`.
Supported kwargs: `seed`, `postprocess`.
"""
circuits = list(circuits)
n_shots_list = Backend._get_n_shots_as_list(
n_shots,
Expand All @@ -256,6 +262,7 @@ def process_circuits(
circuits = noisy_circuits

handle_list: List[Optional[ResultHandle]] = [None] * len(circuits)
seed = kwargs.get("seed")
circuit_batches, batch_order = _batch_circuits(circuits, n_shots_list)

replace_implicit_swaps = self.supports_state or self.supports_unitary
Expand All @@ -273,14 +280,15 @@ def process_circuits(
if self._needs_transpile:
qcs = transpile(qcs, self._qiskit_backend)

seed = cast(Optional[int], kwargs.get("seed"))
job = self._qiskit_backend.run(
qcs,
shots=n_shots,
memory=self._memory,
seed_simulator=seed,
noise_model=self._noise_model,
)
if type(seed) is int:
seed += 1
jobid = job.job_id()
for i, ind in enumerate(indices):
handle = ResultHandle(jobid, i)
Expand Down
3 changes: 1 addition & 2 deletions pytket/extensions/qiskit/backends/ibm.py
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,7 @@ def default_compilation_pass(
passlist = [DecomposeBoxes()]
# If you make changes to the default_compilation_pass,
# then please update this page accordingly
# https://cqcl.github.io/pytket-qiskit/api/index.html#default-compilation
# https://tket.quantinuum.com/extensions/pytket-qiskit/api/index.html#default-compilation
# Edit this docs source file -> pytket-qiskit/docs/intro.txt
if optimisation_level == 0:
if self._supports_rz:
Expand Down Expand Up @@ -510,7 +510,6 @@ def process_circuits(
sampler = Sampler(session=self._session, options=options)
job = sampler.run(
circuits=qcs,
dynamic=self.backend_info.supports_fast_feedforward,
)
job_id = job.job_id()
for i, ind in enumerate(indices_chunk):
Expand Down
3 changes: 2 additions & 1 deletion pytket/extensions/qiskit/backends/ibm_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@


def _batch_circuits(
circuits: Sequence["Circuit"], n_shots: Sequence[Optional[int]]
circuits: Sequence["Circuit"],
n_shots: Sequence[Optional[int]],
) -> Tuple[List[Tuple[Optional[int], List["Circuit"]]], List[List[int]]]:
"""
Groups circuits into sets of circuits with the same number of shots.
Expand Down
5 changes: 4 additions & 1 deletion pytket/extensions/qiskit/backends/ibmq_emulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ def process_circuits(
)

handle_list: List[Optional[ResultHandle]] = [None] * len(circuits)
seed = kwargs.get("seed")
circuit_batches, batch_order = _batch_circuits(circuits, n_shots_list)

batch_id = 0 # identify batches for debug purposes only
Expand Down Expand Up @@ -173,7 +174,9 @@ def process_circuits(
options.resilience_level = 0
options.execution.shots = n_shots
options.simulator.noise_model = self._noise_model
options.seed_simulator = kwargs.get("seed")
options.seed_simulator = seed
if type(seed) is int:
seed += 1
sampler = Sampler(session=self._session, options=options)
job = sampler.run(circuits=qcs)
job_id = job.job_id()
Expand Down
Loading