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

Add local simulation capabilities #8

Merged
merged 28 commits into from
Oct 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
1aed5a2
Add equivalence from reset to initialize(0)
Sep 10, 2023
33c1697
Generalize EnsurePreparationPass
Sep 10, 2023
336f2f7
Add qiskit-aer and pydantic as dependencies
Sep 10, 2023
b64599e
Add new translation plugin for local simulation
Sep 10, 2023
ce8fee4
Add processor utils
Sep 10, 2023
1f18526
Add ProcessorDescription class
Sep 10, 2023
009d0ba
Add PhysicalCatProcessor
Sep 10, 2023
8c675d1
Add SerializedProcessor file format
Sep 10, 2023
da3bd8e
Add InterpolatedProcessor
Sep 10, 2023
3955667
Add InterpolatedProcessor
Sep 10, 2023
e1f097c
Add InterpolatedCatProcessor
Sep 10, 2023
dec5dda
Add proc_to_qiskit translations
Sep 10, 2023
43e7656
Add ProcessorInstructionDurations
Sep 10, 2023
83a5d56
Add coupling maps helpers
Sep 10, 2023
9b0d8fa
Build Qiskit targets from ProcessorDescription
Sep 10, 2023
c4811d5
Add processor fixtures for tests
Sep 10, 2023
3da57d4
Add build_quantum_error_passes
Sep 10, 2023
59a75c2
Add build_readout_noise_model without tests
Sep 10, 2023
479fec4
Add ProcessorSimulator backend
Sep 10, 2023
521d8c9
Add missing readout error tests
Sep 10, 2023
a33570c
Add scheduling tests
Sep 10, 2023
e2e12c8
Add simulation tests
Sep 10, 2023
f25fde2
Add file containing LESCANNE_2020
Sep 10, 2023
3f580a6
Add new AliceBobLocalProvider
Sep 10, 2023
f043ef2
Change list/dict to List/Dict for old Pythons
Sep 10, 2023
3bafac9
Set oldest supported version of Qiskit to 0.43.0
Sep 10, 2023
d991854
Add MANIFEST.in to distribute LESCANNE_2020
Sep 10, 2023
100aca0
Demonstrate local simulation in README
Sep 10, 2023
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
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ jobs:
- name: Install Deps
run: make install
- name: Downgrade Qiskit
run: venv/bin/pip install qiskit==0.41.1
run: venv/bin/pip install qiskit==0.43.0
- name: Install and Run Tests
run: make unit-tests
lint:
Expand Down
3 changes: 3 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
include LICENSE
include README.md
include qiskit_alice_bob_provider/local/resources/*.json
62 changes: 60 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pip install qiskit-alice-bob-provider
`pip` will handle installing all the python dependencies automatically and you
will always install the latest (and well-tested) version.

## Use your Alice & Bob API key
## Remote execution on Alice & Bob QPUs: use your API key

To obtain an API key, please [contact Alice & Bob](https://alice-bob.com/contact/).

Expand All @@ -29,7 +29,7 @@ Where `MY_API_KEY` is your API key to the Alice & Bob API.

```python
print(ab.backends())
backend = ab.get_backend('SINGLE_CAT_SIMULATOR')
backend = ab.get_backend('SINGLE_CAT')
```

The backend can then be used like a regular Qiskit backend:
Expand All @@ -45,3 +45,61 @@ job = execute(c, backend)
res = job.result()
print(res.get_counts())
```

## Local simulation of cat quit processors

This project contains multiple simulators of multi cat qubit processors.

```python
from qiskit_alice_bob_provider import AliceBobLocalProvider
from qiskit import QuantumCircuit, execute, transpile

provider = AliceBobLocalProvider()
print(provider.backends())
# PHYSICAL_CATS_6, PHYSICAL_CATS_40, LESCANNE_2020
```

The `PHYSICAL_CATS` backends are theoretical models of quantum processors made
up of physical cat qubits.
They can be used to study the properties of error correction codes implemented
with physical cat qubits, for different hardware performance levels
(see the parameters of class `PhysicalCatProcessor`).

The `LESCANNE_2020` backend is an interpolated model simulating the processor
used in the [seminal paper](https://arxiv.org/pdf/1907.11729.pdf) by Raphaël
Lescanne in 2020.
This interpolated model is configured to act as a digital twin of the cat qubit
used in this paper.
It does not represent the current performance of Alice & Bob's cat qubits.

The example below schedules and simulates a Bell state preparation circuit on
a `PHYSICAL_CATS_6` processor, for different values of parameters `alpha` and
`kappa_2`.

```python
from qiskit_alice_bob_provider import AliceBobLocalProvider
from qiskit import QuantumCircuit, execute, transpile

provider = AliceBobLocalProvider()

circ = QuantumCircuit(2, 2)
circ.initialize('0+')
circ.cx(0, 1)
circ.measure(0, 0)
circ.measure(1, 1)

# Default 6-qubit QPU with the ratio of memory dissipation rates set to
# k1/k2=1e-5 and cat amplitude alpha set to 4.
backend = provider.get_backend('PHYSICAL_CATS_6')

print(transpile(circ, backend).draw())
# *Displays a timed and scheduled circuit*

print(execute(circ, backend, shots=100000).result().get_counts())
# {'11': 49823, '00': 50177}

# Changing the cat amplitude from 4 (default) to 2 and k1/k2 to 1e-2.
backend = provider.get_backend('PHYSICAL_CATS_6', alpha=2, kappa_2=1e4)
print(execute(circ, backend, shots=100000).result().get_counts())
# {'01': 557, '11': 49422, '10': 596, '00': 49425}
```
11 changes: 8 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,11 @@ urls = {Homepage = "https://github.com/Alice-Bob-SW/qiskit-alice-bob-provider",
requires-python = ">=3.7"
dependencies = [
"requests",
"qiskit-terra>=0.22.0", # first version with backend transpiler plugins
"qiskit-terra>=0.24.0", # required for correct handling of durations
"qiskit-aer",
"qiskit-qir-alice-bob-fork==0.3.2b0",
"tenacity"
"tenacity",
"pydantic>=2.0"
]

[project.optional-dependencies]
Expand All @@ -57,6 +59,7 @@ dev = [

[project.entry-points."qiskit.transpiler.translation"]
state_preparation = "qiskit_alice_bob_provider.translation_plugin:StatePreparationPlugin"
local_state_preparation = "qiskit_alice_bob_provider.local.translation_plugin:LocalStatePreparationPlugin"

[tool.setuptools.packages.find]
include = ["qiskit_alice_bob_provider*"]
Expand All @@ -73,6 +76,8 @@ line_length = 79
module = [
"setuptools",
"qiskit.*",
"qiskit_qir.*"
"qiskit_qir.*",
"qiskit_aer.*",
"scipy.*"
]
ignore_missing_imports = true
1 change: 1 addition & 0 deletions qiskit_alice_bob_provider/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@

# flake8: noqa: F401

from .local import AliceBobLocalProvider
from .provider import AliceBobProvider
15 changes: 14 additions & 1 deletion qiskit_alice_bob_provider/custom_instructions.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

from typing import Optional

from qiskit.circuit import Instruction, InstructionSet, QuantumCircuit
from qiskit.circuit import Instruction, InstructionSet, QuantumCircuit, Reset
from qiskit.circuit.equivalence_library import SessionEquivalenceLibrary
from qiskit.circuit.quantumcircuit import ClbitSpecifier, QubitSpecifier

Expand Down Expand Up @@ -47,3 +47,16 @@ def _measure_x(
SessionEquivalenceLibrary.add_equivalence(
_measure_x_inst, _measure_x_inst.definition
)


# Add an equivalent from Reset to Initialize('0'). This is useful in the case
# of the local provider.
# Although we may want to preserve the Reset instruction for a future behavior
# not yet implemented (e.g., resetting to the void state of the cavity in
# case of cat qubits, which is not how the logical |0> state is encoded), users
# are used to use Reset to actually say Initialize('0').
# That's what this equivalence rule does. If it causes trouble in the future,
# it may be removed.
_c = QuantumCircuit(1, 0)
_c.initialize('0', 0)
SessionEquivalenceLibrary.add_equivalence(Reset(), _c)
16 changes: 14 additions & 2 deletions qiskit_alice_bob_provider/ensure_preparation_pass.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,17 @@
# limitations under the License.
##############################################################################

from qiskit.circuit import Qubit, Reset
from typing import Callable

from qiskit.circuit import Instruction, Qubit, Reset
from qiskit.dagcircuit import DAGCircuit, DAGInNode, DAGOpNode
from qiskit.transpiler import TransformationPass


def _reset_prep() -> Instruction:
return Reset()


class EnsurePreparationPass(TransformationPass):
"""
A transpilation pass that ensures there is a state preparation at the
Expand Down Expand Up @@ -47,6 +53,12 @@ class EnsurePreparationPass(TransformationPass):
from Qiskit to QIR.
"""

def __init__(
self, prep_instruction: Callable[[], Instruction] = _reset_prep
):
super().__init__()
self._prep = prep_instruction

def run(self, dag: DAGCircuit) -> DAGCircuit:
preparations = {'reset', 'initialize', 'state_preparation'}
for node in dag.topological_nodes():
Expand All @@ -62,7 +74,7 @@ def run(self, dag: DAGCircuit) -> DAGCircuit:
new_dag = DAGCircuit()
new_dag.add_qubits(successor.qargs)
new_dag.add_clbits(successor.cargs)
new_dag.apply_operation_back(Reset(), qargs=(node.wire,))
new_dag.apply_operation_back(self._prep(), qargs=(node.wire,))
new_dag.apply_operation_back(
successor.op,
qargs=successor.qargs,
Expand Down
2 changes: 1 addition & 1 deletion qiskit_alice_bob_provider/job.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ def __init__(
self._backend_v2 = backend
self._api_client = api_client
self._circuit = circuit
self._last_response: Optional[dict] = None
self._last_response: Optional[Dict] = None
self._status: Optional[JobStatus] = None
self._counts: Optional[Dict[str, int]] = None
self._files: Dict[str, _DownloadedFile] = {}
Expand Down
19 changes: 19 additions & 0 deletions qiskit_alice_bob_provider/local/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
##############################################################################
# Copyright 2023 Alice & Bob
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
##############################################################################

# flake8: noqa: F401

from .provider import AliceBobLocalProvider
Loading